Skip to content

Harness Differences

Support is not a binary label. A harness can read a canonical format natively, need a harness-specific projection, or expose settings that should stay harness-specific. Two questions matter, and they have different answers per harness: does it read .agents/skills/, and does it read AGENTS.md?

The first question needs a scope before it has an answer. A harness reads project configuration from the repository and user configuration from the home directory, and the two are decided separately: Antigravity reads .agents/skills/ in a workspace but keeps its user skills under ~/.gemini/config/skills/. So the table below asks about skills twice.

HarnessReads .agents/skills/ in a repositoryReads ~/.agents/skills/Reads AGENTS.mdNeeds
CodexYes (primary path, walks up to the repository root)YesYesNothing
GitHub CopilotYes (also .github/skills/, .claude/skills/)Yes (also ~/.copilot/skills/)YesNothing
Devin DesktopYes (first of nine scanned paths, and recommended)Not establishedNot establishedNothing
AntigravityYes (<workspace-root>/.agents/skills/)No (~/.gemini/config/skills/)Not establishedNothing
VS CodeYes (same path set as Copilot CLI)Yes (same path set as Copilot CLI)YesNothing
CursorYes (also .cursor/skills/)Yes (also ~/.cursor/skills/)Agent mode onlyAttention to the mode split
Claude CodeNoNo (~/.claude/skills/)NoSkills projection + CLAUDE.md
Gemini CLIYes (alias, takes precedence over .gemini/skills/)Yes (alias for ~/.gemini/skills/)Only once configuredSettings edit

Only Claude Code needs a skills projection. Every other harness in the table reads the canonical directory in a repository. The three with pages of their own are there because each has a gap that costs you instructions if you miss it — and Gemini CLI is the case that shows the two questions are independent: it reads the canonical skills directory and still reads no instructions until context.fileName says so.

Only the repository column decides whether a projection gets written. The user column is here because the same skills can be installed there and the failure mode is identical, and because a harness answering differently in the two columns — Antigravity does — is otherwise invisible. Nothing is written outside the repository.

Where each harness keeps its project-scope MCP servers is a third question, with a third answer set — four different files across two formats, and two harnesses with no documented project-scope file at all. That table lives on MCP Servers.

Devin Desktop was named Windsurf until the rebrand on 2026-06-02. --harness windsurf is still accepted as a deprecated alias, and still writes the legacy .windsurf/skills projection because Devin continues to scan that path; What a projection is covers how it is reported.

Vendor documentation changes independently. Follow the linked vendor documentation for setup requirements, product editions, and features beyond skills and instructions. The confidence behind each row is recorded in Sources & Confidence.

Nested instruction files resolve differently

Section titled “Nested instruction files resolve differently”

The two-question table asks whether a harness reads AGENTS.md. For a repository with nested instruction files, “yes” is not the whole answer. Harnesses disagree about what happens when more than one file applies.

RuleOn conflict
AGENTS.md, publishedThe closest file winsThe closest file governs
AGENTS.md v1.1, proposedGuidance accumulates down the treeMore specific instructions take precedence
Claude CodeAll discovered files are concatenatedUndefined: “Claude may pick one arbitrarily”

Claude Code’s model is additive: every CLAUDE.md from the filesystem root down to the working directory is loaded, ordered so the nearest is read last. Proximity buys recency, not authority.

This matters when a nested file is written to contradict its parent: “this package uses vitest, not jest.” Under the published rule that override is the point; under Claude Code both statements arrive together with no rule for choosing. So a nested instruction file behaves as intended for Codex and Cursor, and lands as a contradiction for Claude Code.

Two things follow for authoring:

  • Make a nested file self-sufficient on any topic it touches, rather than relying on inheritance. This is correct under all three models above, which is why it is the portable choice. The cost is some duplication that the proposed v1.1 accumulation model would make unnecessary.
  • Prefer additive local content over contradiction. A nested file that adds package-specific facts is unambiguous everywhere. One that reverses a root rule is only unambiguous where override is implemented.

Claude Code’s claudeMdExcludes setting can drop unwanted ancestor files, but it subtracts whole files rather than resolving conflicts. It is a mitigation, not an implementation of the standard’s rule.

Because the standard’s own semantics are unratified, treat this divergence as a moving target rather than a stable difference. Confidence is recorded in Sources & Confidence.

JSON configuration disagrees about comments

Section titled “JSON configuration disagrees about comments”

Two harnesses keep project-scope configuration in a file named settings.json, and they disagree about what that name allows.

FileCommentsWhat a comment does
.gemini/settings.jsonLegalThe loader strips them before parsing, so a user’s file may legitimately carry them
.claude/settings.jsonRejectedThe file fails to parse, and a settings file that fails validation is rejected as a whole rather than in part

Both halves matter when something edits one of these files for you. On the Gemini CLI side, the obvious implementation — read the file, JSON.parse it, add the entry, write the object back — is silent data loss: every comment the author wrote disappears, along with their key order and indentation. Edit the one array in place instead. On the Claude Code side the failure is the reverse and louder: a comment added to annotate a permission or hook entry invalidates the entire file.

The rule that survives both is to treat a user-authored settings file as text to amend rather than an object to round-trip. Skill: init states it as a rule for that reason.

Confidence for both rows is recorded in Sources & Confidence.

Gemini CLI and Antigravity are both Google’s, and it is tempting to treat them as one target. They agree in the repository column — both read .agents/skills/ there and need no projection — and disagree everywhere else.

Antigravity’s global skills live under ~/.gemini/config/skills/, which belongs to a different product, so the canonical user path is Gemini CLI’s and not Antigravity’s. Gemini CLI is selectable via --harness and detected on .gemini/; Antigravity documents no project-scope directory and is not registered at all. Gemini CLI needs an instruction bridge; whether Antigravity reads AGENTS.md is not established. Enabling one says nothing about the other.

They were on opposite sides of the projection line until 2026-08-18, when Gemini CLI’s workspace-scope alias was confirmed against the vendor’s source. The pairing is worth keeping as a caution: one brand is not one target.

Antigravity and VS Code read the canonical directory but are not selectable via --harness, because harness registration exists to decide projections and detection, and neither needs either.

Neither has a safe project-scope detection marker. Antigravity documents no project harness directory, and VS Code’s .vscode/ indicates the editor rather than skills support. It exists in repositories with no agent configuration at all, so detecting on it would enable a harness almost everywhere. Registering them would add a name to the reported enabled set, write zero files, and introduce a false positive. Documenting them is the useful part.

Section titled “Enabling states support, projecting writes a link”

Enabling a harness is a statement about what the repository supports. For the five native harnesses above, no files are written at all. The CLI result separates native from linked so it is clear what actually changed on disk.

Which harnesses get enabled, and why a detected directory does not by itself mean you want that harness maintained, is covered in Skill: init.

The skills CLI is the reference implementation of canonical storage plus per-harness links, and its scope is a useful sanity check on the table above. Its public agent listing names twenty:

Claude Code, Cursor, Codex, GitHub Copilot, Windsurf, Gemini, Cline, AMP, Antigravity, OpenClaw, Droid, Goose, Kilo, Kiro CLI, Nous Research, OpenCode, Roo, Trae, VS Code, and Zed.

Two caveats. The vercel-labs/skills README claims 75 supported agents while the listing shows twenty; the discrepancy is unresolved, so prefer the list to the number. And the listing still says “Windsurf”, so it has not yet caught up with the Devin Desktop rebrand.

Buddy Agent Harness prefers direct consumption of the canonical format. Where a harness needs another location, it projects a compatible artifact by link or copy. It does not translate policy into an undocumented harness format, and it does not overwrite existing user-owned configuration.

The directory-level link is supported in practice rather than guaranteed by contract. Claude Code covers what the vendor documents, why the directory link is preferred anyway, and the documented fallback.