Skip to content

fix(platform): detect legacy CPU incompatibility before Antigravity migration prompt (#27342) - #29426

Closed
dylanyunlon wants to merge 1 commit into
google-gemini:mainfrom
dylanyunlon:fix/legacy-cpu-avx-compatibility-27342
Closed

dylanyunlon wants to merge 1 commit into
google-gemini:mainfrom
dylanyunlon:fix/legacy-cpu-avx-compatibility-27342

Conversation

@dylanyunlon

Copy link
Copy Markdown

Summary

This PR addresses an issue where users with legacy CPUs (e.g. AMD
A-Series/Llano, Intel Core 2 Duo) that lack AVX/AVX2 instruction sets
are shown the Antigravity CLI installation command, even though the
Go-based binary will crash immediately with SIGILL (exit code 132) on
their hardware.

By adding runtime CPU feature detection and integrating it into the
migration banner, help command, and telemetry pipeline, we ensure that:

  1. Users on incompatible hardware see a clear warning instead of an
    install command that leads to a crash.
  2. The Gemini team can track how many active users have legacy CPUs
    via telemetry to plan baseline x86-64-v1 builds.

Details

  1. CPU Feature Detection: New cpuCompatibility.ts service in
    packages/core reads /proc/cpuinfo (Linux), queries sysctl (macOS),
    or applies model-string heuristics (Windows) to detect SSE4.2, AVX,
    AVX2, and AES-NI support. Determines x86-64 microarchitecture level
    (v1/v2/v3/v4) and compatibility with GOAMD64=v3 binaries.

  2. Platform Diagnostics: New platformDiagnostics.ts service
    provides a cached, process-lifetime compatibility check and a
    formatted diagnostics report for bug reports and /stats output.

  3. Banner Suppression: useBanner.ts now calls
    getAntigravityCompatibility(), on incompatible CPUs, the install
    command is replaced with a yellow warning explaining the hardware
    limitation and directing users to continue with Gemini CLI (Node.js).

  4. Help Command: helpCommand.ts checks CPU compatibility when
    users query /help install antigravity or /help antigravity cpu.
    Incompatible systems see the hardware warning with a link to Compatibility Issue: Antigravity CLI requires AVX instructions missing on legacy CPUs (AMD A-Series) #27342.

  5. Telemetry Enrichment: Three new EventMetadataKeys (203–205)
    added to clearcut-logger START_SESSION events:
    CPU_MICROARCH_LEVEL, CPU_ANTIGRAVITY_COMPAT, CPU_MISSING_FEATURES.

  6. Gateway Auth: Fixed validateAuthMethod to recognize the
    GATEWAY auth type triggered by GOOGLE_GEMINI_BASE_URL.

  7. Automated Verification:

    • 24 unit tests in cpuCompatibility.test.ts covering Linux
      /proc/cpuinfo parsing (including AMD A6-3420M from the original
      issue), macOS sysctl, Windows model heuristics, ARM passthrough,
      and edge cases.
    • 6 unit tests in platformDiagnostics.test.ts for caching,
      report building, and formatting.
    • Updated tests in antigravityUtils, useBanner, and helpCommand
      with mock-based CPU compatibility injection.

Related Issues

Resolves #27342, Compatibility Issue: Antigravity CLI requires AVX
instructions missing on legacy CPUs (AMD A-Series)

How to Validate

  1. Run the CPU compatibility test suite:
    npm test -w @google/gemini-cli-core -- src/services/cpuCompatibility.test.ts --run
  2. Run the platform diagnostics test suite:
    npm test -w @google/gemini-cli-core -- src/services/platformDiagnostics.test.ts --run
  3. Run the CLI banner and help command tests:
    npm test -w @google/gemini-cli -- src/ui/hooks/useBanner.test.ts --run
    npm test -w @google/gemini-cli -- src/ui/commands/helpCommand.test.ts --run
    npm test -w @google/gemini-cli -- src/ui/utils/antigravityUtils.test.ts --run
  4. Run project-wide linting and type checking:
    npm run build

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • Linux
      • npm run

…igration prompt (google-gemini#27342)

## Summary

This PR addresses an issue where users with legacy CPUs (e.g. AMD
A-Series/Llano, Intel Core 2 Duo) that lack AVX/AVX2 instruction sets
are shown the Antigravity CLI installation command, even though the
Go-based binary will crash immediately with SIGILL (exit code 132) on
their hardware.

By adding runtime CPU feature detection and integrating it into the
migration banner, help command, and telemetry pipeline, we ensure that:
1. Users on incompatible hardware see a clear warning instead of an
   install command that leads to a crash.
2. The Gemini team can track how many active users have legacy CPUs
   via telemetry to plan baseline x86-64-v1 builds.

## Details

1. **CPU Feature Detection:** New `cpuCompatibility.ts` service in
   `packages/core` reads /proc/cpuinfo (Linux), queries sysctl (macOS),
   or applies model-string heuristics (Windows) to detect SSE4.2, AVX,
   AVX2, and AES-NI support. Determines x86-64 microarchitecture level
   (v1/v2/v3/v4) and compatibility with GOAMD64=v3 binaries.

2. **Platform Diagnostics:** New `platformDiagnostics.ts` service
   provides a cached, process-lifetime compatibility check and a
   formatted diagnostics report for bug reports and /stats output.

3. **Banner Suppression:** `useBanner.ts` now calls
   `getAntigravityCompatibility()`, on incompatible CPUs, the install
   command is replaced with a yellow warning explaining the hardware
   limitation and directing users to continue with Gemini CLI (Node.js).

4. **Help Command:** `helpCommand.ts` checks CPU compatibility when
   users query `/help install antigravity` or `/help antigravity cpu`.
   Incompatible systems see the hardware warning with a link to google-gemini#27342.

5. **Telemetry Enrichment:** Three new EventMetadataKeys (203–205)
   added to clearcut-logger START_SESSION events:
   CPU_MICROARCH_LEVEL, CPU_ANTIGRAVITY_COMPAT, CPU_MISSING_FEATURES.

6. **Gateway Auth:** Fixed `validateAuthMethod` to recognize the
   GATEWAY auth type triggered by GOOGLE_GEMINI_BASE_URL.

7. **Automated Verification:**
   - 24 unit tests in cpuCompatibility.test.ts covering Linux
     /proc/cpuinfo parsing (including AMD A6-3420M from the original
     issue), macOS sysctl, Windows model heuristics, ARM passthrough,
     and edge cases.
   - 6 unit tests in platformDiagnostics.test.ts for caching,
     report building, and formatting.
   - Updated tests in antigravityUtils, useBanner, and helpCommand
     with mock-based CPU compatibility injection.

## Related Issues

Resolves google-gemini#27342, Compatibility Issue: Antigravity CLI requires AVX
instructions missing on legacy CPUs (AMD A-Series)

## How to Validate

1. Run the CPU compatibility test suite:
   ```bash
   npm test -w @google/gemini-cli-core -- src/services/cpuCompatibility.test.ts --run
   ```
2. Run the platform diagnostics test suite:
   ```bash
   npm test -w @google/gemini-cli-core -- src/services/platformDiagnostics.test.ts --run
   ```
3. Run the CLI banner and help command tests:
   ```bash
   npm test -w @google/gemini-cli -- src/ui/hooks/useBanner.test.ts --run
   npm test -w @google/gemini-cli -- src/ui/commands/helpCommand.test.ts --run
   npm test -w @google/gemini-cli -- src/ui/utils/antigravityUtils.test.ts --run
   ```
4. Run project-wide linting and type checking:
   ```bash
   npm run build
   ```

## Pre-Merge Checklist

- [ ] Updated relevant documentation and README (if needed)
- [x] Added/updated tests (if needed)
- [ ] Noted breaking changes (if any)
- [x] Validated on required platforms/methods:
  - [x] Linux
    - [x] npm run
@dylanyunlon
dylanyunlon requested a review from a team as a code owner September 20, 2026 12:47
@github-actions github-actions Bot added the size/xl An extra large PR label Sep 20, 2026
@github-actions

Copy link
Copy Markdown

📊 PR Size: size/XL

  • Lines changed: 1481
  • Additions: +1428
  • Deletions: -53
  • Files changed: 16

@github-actions

Copy link
Copy Markdown

You already have 7 pull requests open. Please work on getting existing PRs merged before opening more.

@dylanyunlon

Copy link
Copy Markdown
Author

/gemini review

@github-actions github-actions Bot closed this Sep 20, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces runtime CPU feature detection to prevent users with legacy hardware from attempting to install the Antigravity CLI, which requires AVX/AVX2 instruction sets. By proactively identifying incompatible systems, the CLI now provides clear warnings instead of failing with a crash, while also enriching telemetry data to better inform future development and support for older CPU architectures.

Highlights

  • CPU Feature Detection: Introduced a new service to detect AVX and AVX2 instruction set support across Linux, macOS, and Windows to identify legacy hardware that cannot run the Antigravity CLI.
  • User Experience: Updated the Antigravity CLI migration banner and help commands to display a clear hardware warning instead of installation instructions for incompatible CPUs.
  • Telemetry Enrichment: Added CPU microarchitecture and compatibility status to session telemetry to help the team plan future build baselines for legacy hardware.
  • Authentication Fix: Updated the authentication validation logic to correctly recognize and support GATEWAY auth methods.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces CPU compatibility detection and platform diagnostics to ensure the host system meets the hardware requirements (specifically x86-64-v3 / AVX2) of the Go-based Antigravity CLI binary, preventing SIGILL crashes on legacy CPUs. It adds compatibility checks in the help command, banner hooks, and telemetry, along with comprehensive unit tests. The review feedback suggests implementing the environment variable bypass GEMINI_CPU_COMPAT_SKIP in the production code to allow skipping compatibility checks, and using optional chaining with trimming when parsing CPU model strings to prevent potential runtime errors.

Note: Security Review did not run due to the size of the PR.

Comment on lines +194 to +195
export function checkCpuCompatibility(): CpuCompatibilityResult {
const cpus = os.cpus();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The environment variable GEMINI_CPU_COMPAT_SKIP was added to the TestRig clean environment list in packages/test-utils/src/test-rig.ts, but its handling is not implemented in the production code. This means the bypass flag has no effect. Please implement the check at the beginning of checkCpuCompatibility to allow skipping the compatibility check when the environment variable is set.

export function checkCpuCompatibility(): CpuCompatibilityResult {
  if (process.env['GEMINI_CPU_COMPAT_SKIP'] === '1' || process.env['GEMINI_CPU_COMPAT_SKIP'] === 'true') {
    return {
      compatible: true,
      cpuModel: 'Skipped via env',
      arch: process.arch,
      microarchLevel: 'unknown',
      features: { sse42: true, avx: true, avx2: true, aesni: true },
      missingFeatures: [],
    };
  }
  const cpus = os.cpus();

return { sse42: false, avx: false, avx2: false, aesni: false };
}

const model = cpus[0].model.toLowerCase();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

To prevent potential runtime TypeErrors if cpus[0] or cpus[0].model is undefined, use optional chaining. Additionally, when using an optional string with a fallback value, trim the optional string and use the fallback if the result is empty to avoid uninformative messages from whitespace-only strings.

Suggested change
const model = cpus[0].model.toLowerCase();
const model = cpus[0]?.model?.trim().toLowerCase() || '';
References
  1. When using an optional string with a fallback value, trim the optional string and use the fallback if the result is empty to avoid uninformative messages from whitespace-only strings.
  2. When consuming an object, if a property is optional in its type definition (interface), callers must handle the undefined case (e.g., by providing a default with ??). Do not rely on the implementation details of the function that creates the object to always provide a value, as this can change. Code against the interface contract.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces CPU compatibility detection and platform diagnostics to warn users if their hardware lacks the required instruction sets (AVX/AVX2, SSE4.2) to run the Go-based Antigravity CLI binary, preventing SIGILL crashes. It integrates these checks into the CLI banner, help commands, and telemetry tracking, and updates gateway authentication validation. The reviewer's feedback focuses on making the CPU feature detection more robust by handling failures gracefully and failing-safe (assuming compatibility) to avoid false-positive warnings on modern CPUs in restricted environments. Additionally, the reviewer highlights a violation of the repository's rule against using module-level global variables for state caching in platformDiagnostics.ts.

Comment on lines +56 to +79
export function detectCpuFeatures(): CpuFeatureFlags {
const defaultFlags: CpuFeatureFlags = {
sse42: false,
avx: false,
avx2: false,
aesni: false,
};

try {
if (process.platform === 'linux') {
return detectCpuFeaturesLinux();
} else if (process.platform === 'darwin') {
return detectCpuFeaturesDarwin();
} else if (process.platform === 'win32') {
return detectCpuFeaturesWindows();
}
} catch (error) {
debugLogger.debug(
`Failed to detect CPU features: ${error instanceof Error ? error.message : String(error)}`,
);
}

return defaultFlags;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If CPU feature detection fails or is inconclusive (e.g., due to permission issues, sandboxing, or restricted environments), returning all-false default flags will cause modern CPUs to be falsely reported as incompatible. Returning null allows the caller to handle inconclusive detection with a fail-safe default (assuming compatibility).

export function detectCpuFeatures(): CpuFeatureFlags | null {
  try {
    if (process.platform === 'linux') {
      return detectCpuFeaturesLinux();
    } else if (process.platform === 'darwin') {
      return detectCpuFeaturesDarwin();
    } else if (process.platform === 'win32') {
      return detectCpuFeaturesWindows();
    }
  } catch (error) {
    debugLogger.debug(
      `Failed to detect CPU features: ${error instanceof Error ? error.message : String(error)}`
    );
  }

  return null;
}

Comment on lines +90 to +92
if (!flagsLine) {
return { sse42: false, avx: false, avx2: false, aesni: false };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If the flags line is missing in /proc/cpuinfo, returning all-false flags will cause a false-positive incompatibility warning. Throwing an error allows the caller to treat this as an inconclusive detection and fail-safe.

Suggested change
if (!flagsLine) {
return { sse42: false, avx: false, avx2: false, aesni: false };
}
if (!flagsLine) {
throw new Error('No flags line found in /proc/cpuinfo');
}

Comment on lines +107 to +126
function detectCpuFeaturesDarwin(): CpuFeatureFlags {
const query = (key: string): boolean => {
try {
const output = execFileSync('sysctl', ['-n', key], {
encoding: 'utf-8',
timeout: 5000,
}).trim();
return output === '1';
} catch {
return false;
}
};

return {
sse42: query('hw.optional.sse4_2'),
avx: query('hw.optional.avx1_0'),
avx2: query('hw.optional.avx2_0'),
aesni: query('hw.optional.aes'),
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If sysctl queries fail completely (e.g., command not found or permission denied), returning all-false flags will cause a false-positive incompatibility warning on macOS. Tracking query success and throwing an error allows the caller to fail-safe.

function detectCpuFeaturesDarwin(): CpuFeatureFlags {
  let success = false;
  const query = (key: string): boolean => {
    try {
      const output = execFileSync('sysctl', ['-n', key], {
        encoding: 'utf-8',
        timeout: 5000,
      }).trim();
      success = true;
      return output === '1';
    } catch {
      return false;
    }
  };

  const features = {
    sse42: query('hw.optional.sse4_2'),
    avx: query('hw.optional.avx1_0'),
    avx2: query('hw.optional.avx2_0'),
    aesni: query('hw.optional.aes'),
  };

  if (!success) {
    throw new Error('sysctl queries failed');
  }

  return features;
}

Comment on lines +136 to +138
if (!cpus || cpus.length === 0) {
return { sse42: false, avx: false, avx2: false, aesni: false };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If os.cpus() returns empty or invalid data, throwing an error allows the caller to treat this as inconclusive and fail-safe.

Suggested change
if (!cpus || cpus.length === 0) {
return { sse42: false, avx: false, avx2: false, aesni: false };
}
if (!cpus || cpus.length === 0) {
throw new Error('os.cpus() returned empty or invalid data');
}

Comment on lines +194 to +221
export function checkCpuCompatibility(): CpuCompatibilityResult {
const cpus = os.cpus();
const cpuModel = cpus && cpus.length > 0 ? cpus[0].model : 'Unknown';
const arch = process.arch;
const features = detectCpuFeatures();
const microarchLevel = getMicroarchLevel(features);

const missingFeatures: string[] = [];
for (const feature of REQUIRED_FEATURES) {
if (!features[feature]) {
missingFeatures.push(feature.toUpperCase());
}
}

// Non-x86 architectures (ARM, etc.) are always considered compatible
// because Antigravity provides separate binaries for those platforms.
const isNonX86 = arch !== 'x64' && arch !== 'ia32';
const compatible = isNonX86 || missingFeatures.length === 0;

return {
compatible,
cpuModel,
arch,
microarchLevel,
features,
missingFeatures,
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Handle the case where detectCpuFeatures() returns null (inconclusive detection) by failing-safe and assuming compatibility, preventing false-positive warnings on modern CPUs in restricted environments.

export function checkCpuCompatibility(): CpuCompatibilityResult {
  const cpus = os.cpus();
  const cpuModel = cpus && cpus.length > 0 ? cpus[0].model : 'Unknown';
  const arch = process.arch;
  const features = detectCpuFeatures();

  if (!features) {
    return {
      compatible: true,
      cpuModel,
      arch,
      microarchLevel: 'unknown',
      features: { sse42: true, avx: true, avx2: true, aesni: true },
      missingFeatures: [],
    };
  }

  const microarchLevel = getMicroarchLevel(features);

  const missingFeatures: string[] = [];
  for (const feature of REQUIRED_FEATURES) {
    if (!features[feature]) {
      missingFeatures.push(feature.toUpperCase());
    }
  }

  // Non-x86 architectures (ARM, etc.) are always considered compatible
  // because Antigravity provides separate binaries for those platforms.
  const isNonX86 = arch !== 'x64' && arch !== 'ia32';
  const compatible = isNonX86 || missingFeatures.length === 0;

  return {
    compatible,
    cpuModel,
    arch,
    microarchLevel,
    features,
    missingFeatures,
  };
}

* Cached compatibility result to avoid redundant /proc/cpuinfo reads or
* sysctl invocations within the same process lifetime.
*/
let cachedCompatibility: CpuCompatibilityResult | null = null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

This module-level global variable cachedCompatibility is used as a cache, which violates the repository's general rule: 'Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.' Consider refactoring this to use session-scoped or instance-scoped state, or leverage a standard cache implementation.

References
  1. Avoid module-level global variables for state like caches to prevent race conditions and memory issues in concurrent environments. Instead, use session-scoped or instance-scoped state and leverage standard cache implementations like LRUCache.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl An extra large PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compatibility Issue: Antigravity CLI requires AVX instructions missing on legacy CPUs (AMD A-Series)

1 participant