Book a call
LESSON16mVERIFIED 2026-08-05 · CLAUDE CODE 2.1.221 · CODEX CLI 0.146.0 · GITHUB COPILOT CLI 1.0.78 · ANTIGRAVITY CLI 1.1.10 · KIMI CODE CLI 0.31.1

Standardising a setup without a mandate

Nobody on your team has the authority to pick everyone's harness. What actually travels in the repo, what needs each person's consent, and what only CI can enforce.

The mandate exists, and it isn't yours

You could say there's top-down control but you probably don't own the lever.

Vendors delivering actual enforcement layers:

  • Claude Code — the managed policy settings, marked as "cannot be overridden" in the precedence table and above anything a dev can set, as well as an organisation-wide CLAUDE.md file which they deploy to a fixed path on every machine

  • GitHub Copilot CLI — it allows you to pin the model, reasoning effort and context tier for each session started within a trusted repository

  • Cursor — has centralised rules administration from a dashboard, on Team and Enterprise plans

But… For all of these, there's a delivery channel which you might not own:

  • The managed CLAUDE.md file? Claude Code docs say to distribute it using MDM, Group Policy or Ansible

  • The repository pin in Copilot CLI? It only counts where the working directory has been trusted, and that happens on each person's machine

  • The centralised rules administration in Cursor? It's about a plan

So — Every lever is in the hands of whoever has the device management or a billing relationship, not in the hands of the dev who's seen three people in their team editing the generated migrations with their LLM for the last couple of weeks and wants to have it resolved.

What we should ask ourselves instead is: what can we put in the repository that will be useful for whoever shows up with whatever tool they have, without needing anyone's agreement?

The vendors started reading each other's files

Vendors started respecting each other's files — recently, there's been a convergence around filenames, not around tools.

AGENTS.md — we'd say it's read by 5 out of 6:

  • Codex — we've checked with codex debug prompt-input which outputs what the model sees as the prompt input in JSON, no call being made; there's the contents of AGENTS.md in there

  • Copilot CLI — it's mentioned in the help text, where they talk about the flag that disables custom instructions from AGENTS.md and related files

  • Cursor — docs mention it for any subdirectory, saying it's used when the agent is working on files under it

  • Antigravity — parses GEMINI.md or AGENTS.md at the root of the workspace on startup

  • Kimi Code — the same

Claude Code is the only exception here; they say explicitly in their docs they read CLAUDE.md, not AGENTS.md.

The same for the skills directories — they seem to work the same way:

  • We've created a SKILL.md file with the same content and put it in three project directories, creating scratch directories for each of them, and ran copilot skill list. It showed us .github/skills/, .agents/skills/ and .claude/skills/ as project skills

  • Codex found the file in .agents/skills/ and .codex/skills/

  • Cursor's docs are actually the most explicit here — they list .claude/skills/ and .codex/skills/ under compatibility, saying it's because other vendors put their skills there

  • And GitHub go even further in their Copilot CLI configuration reference — they list .claude/settings.json there under cross-tool support as shared repository settings

But — It's not perfect, and the gaps define what you commit to your repo:

  • .agents/skills/ — that's the most universal directory, read by 5 out of 6 (by everyone but Claude Code)

  • .claude/skills/ — this one is accessible for 3: Claude Code, Copilot CLI and Cursor; not for Codex

If you create a scratch dir with a single AGENTS.md in it and put a marker file only in .claude/skills/, the marker won't appear in Codex's prompt input; the AGENTS.md from the same directory will be there.

One file of facts, and adapters with no facts in them

So: one file with the facts, and zero-one adapters per tool that needs a different filename.

Let's commit AGENTS.md to the root of the project, and create one adapter per tool that expects a different name.

For example — for Claude Code, you can create CLAUDE.md with an import pointing at AGENTS.md:

MARKDOWN
@AGENTS.md

If you create a scratch dir and put AGENTS.md in it saying the project codename is BLUEHERON, and then run a headless version of Claude Code under it, asking it what the project name is, it'll answer with "BLUEHERON". If you create another scratch dir with a different project name, and no adapter, it'll answer with "NONE".

A symlink works too (ln -s AGENTS.md CLAUDE.md) but might require admin rights or Developer Mode on Windows, so the import is usually more bulletproof in mixed teams.

Just remember — an adapter can't contain any actual instructions; the day you append a real one to CLAUDE.md there are two sources of truth about your project, with the conflict being invisible and showing up only as two colleagues whose agents behave differently. Anything below the import should be about that tool, not your project.

Make sure you commit adapters for tools nobody uses yet — one line per file. Otherwise somebody will clone the repo with an unconfigured harness, won't find anything, will create their own file in their own place and the divergence will remain silent until it contradicts you in a review.

Facts travel, defaults negotiate, enforcement doesn't travel at all

There are three tiers of things that can be put into the repo:

  • Facts — AGENTS.md, skills, rules; no per-person configuration; the only thing standing between "I committed my instructions" and "My colleague started a session" is their tool asking them if they want to trust an unfamiliar directory; works after a git pull and is almost free — and it's where most of the value is

  • Defaults — allow-lists, model pin, MCP server list, hooks; an offer rather than an instruction, and any harness that supports a repo-level configuration file gates it:

    • Codex loads .codex/config.toml only for trusted projects — we've created a scratch repo with it and ran codex doctor, and it showed us the user-level file but not the one from the project directory

    • Claude Code puts hooks and the settings that run them behind the workspace trust prompt

    • Copilot CLI has 14 keys in the repository level configuration and, as they put it, "any other keys — including keys that are valid in the user configuration file — are silently ignored"; model and reasoning effort pins work only when the working directory is trusted

    • If there's no repo-level config file at all — there's no tier two

  • Enforcement — doesn't travel:

    • Copilot CLI has a disableAllHooks key that disables hooks in the repo and the user configuration file

    • Claude Code has --safe-mode and --bare flags that start a session with hooks and CLAUDE.md discovery disabled

    • Codex refuses to run a hook from the repo until you trust it

So be prepared some part of your team will run without your defaults at all times; make sure it doesn't cost them anything.

That's a feature, not a bug; it's sensible for pieces of software that run shell commands on other people's laptops. If sth needs to hold — make sure it's checked somewhere where devs aren't — in CI, as a required status check or as a server-side hook.

So — facts in the repo, gates in CI, let go of trying to enforce the middle layer.

Ship it as a fix, not as a policy

This is a "fix" for an incident, not a policy. Standards that work are PRs that resolve sth that's already happened:

  • If you create a PR that introduces an AI agent setup standard — it's a discussion; if you create one with 4 lines in AGENTS.md the morning after your agent edited a generated migration by hand — it's one question, "Will this prevent it?", and merge

  • Also — such a PR is honest about where it comes from; every line in a good instructions file is the residue of sth that went wrong once

It's about a repo and a person, and an incident. Not about a team and a vote. Just like the linter config — your setup will build itself through review.

Leave the escape hatch in the file, and write it down

Leave the "personal override" route in the file, but document it:

  • .claude/settings.local.json and CLAUDE.local.md

  • .github/copilot/settings.local.json

  • ~/.codex/config.toml

  • Personal skills directories under ~/.agents/skills/

And list these paths in your AGENTS.md, right next to the shared configuration.

People will adopt standards that come with opt-outs; they'll ignore ones that don't. The latter is worse, because they were ignoring it for a reason.

But be careful — if you run Claude Code under a repo and it creates .claude/settings.local.json in there, it adds that line to the global git excludes file on your machine, not to the repo's .gitignore. So make sure to add this line to the repo's .gitignore on day one so nobody can commit their personal overrides into other people's sessions.

IN YOUR HARNESS

In Claude Code

Configuration files specific to Claude Code — the files that are tracked within the repository and therefore available for everyone who clones it:

  • CLAUDE.md (or .claude/CLAUDE.md)

  • Per-subject files placed in .claude/rules/

  • Skills stored in .claude/skills/

  • .claude/settings.json — as the documentation puts it, "settings that are checked into source control and shared with your team"

Individual-only files that are not versioned:

  • ~/.claude/settings.json

  • .claude/settings.local.json

  • CLAUDE.local.md

If you're working on a project with a team using multiple tools, it might make sense to create CLAUDE.md with an import of AGENTS.md and append some Claude-specific instructions underneath. Like this (a small Markdown file):

MARKDOWN
@AGENTS.md

## Claude Code

Use plan mode for changes under `src/billing/`.

Which tells Claude that it should be in plan mode for any changes made to the src/billing directory.

In general, before placing anything in version control, it's important to keep in mind:

  • Everything that runs — hooks, as well as some configuration parameters defined in the documentation, like autoMemoryDirectory — is enabled only after the user approves the workspace trust prompt that appears in the folder; if it's a team setup, the hook stays inert until a team member does this

  • If you import a file from another location (an import in a project-level file that resolves outside the working directory), the documentation says that the first time this happens, an approval prompt appears. If you deny it, "the imports stay disabled and the dialog doesn't appear again"; if a teammate does that, there's no error anywhere, they're just missing a part of the instructions

  • You can check what was actually loaded using /context (in its Memory files section), which is more reliable than asking Claude about it, and the first thing we'd try if one of your teammates were to tell you that the setup doesn't work

In Codex CLI

What is version-controlled: anything that's in the repo — both AGENTS.md at the root of the repository, and in subfolders, as well as skills under either .agents/skills/ or .codex/skills/. We checked both with a canary: a SKILL.md file in either place showed up, with its resolved path, in the input prompt the LLM sees.

What's set at the user level: ~/.codex/config.toml, and, if you use multiple profiles (with --profile), ~/.codex/<name>.config.toml.

A middle layer: .codex/config.toml which is committable but only read in projects that are set as trusted. We created a scratch repo with one and ran codex doctor, and the Configuration section listed just ~/.codex/config.toml there, as we hadn't trusted that project yet.

Same goes for hooks — a committed one won't run until that person trusts the project. That's what --dangerously-bypass-hook-trust is for, described in the help as running enabled hooks "without requiring persisted hook trust for this invocation".

We even have a tool for that — codex debug prompt-input which prints (in JSON) what will be sent as an input prompt to the LLM. No request, no cost. You can even pipe it through a formatter and filter by AGENTS.md if you want, to see the differences in terms of what your setup (or your teammate's) actually sources versus what you assume it sources, which is the most cost-efficient way for 2 team members to do it.

BASH
codex debug prompt-input | python3 -m json.tool | grep -i agents.md

In GitHub Copilot CLI

The version-controlled parts:

  • AGENTS.md

  • .github/copilot-instructions.md (created by copilot init based on the files found in the repo)

  • .github/skills/

  • .github/agents/

  • .github/hooks/

  • .github/copilot/settings.json (repo-wide config)

These are in the .github folder, which is a standard place for repo-level configuration in GitHub.

The user-specific parts, under ~/.copilot:

  • settings.json

  • mcp-config.json

  • permissions-config.json

  • skills/

Plus .github/copilot/settings.local.json, which the documentation tells you to add to .gitignore yourself.

Generally, the skill discovery works based on three directories that are part of the repository, two of which belong to other vendors:

  • .github/skills/

  • .agents/skills/

  • .claude/skills/

The copilot skill --help command lists exactly these three, and we confirmed all of them — the same canary SKILL.md, dropped into each in turn, came back as a project skill every time. Also, the same documentation mentions .claude/settings.json and .claude/settings.local.json under cross-tool support.

But…

If you define a file at the repo level with settings, it can only have 14 keys:

  • model

  • effortLevel

  • contextTier

  • hooks

  • disableAllHooks

  • disabledMcpServers

  • disabledSkills

  • deniedUrls

  • respectGitignore

  • and a handful more

Anything else is silently ignored. Even if it's a key that's valid at the user level, in settings.json.

The model / effortLevel / contextTier keys only work in trusted working directories.

In Cursor

It's worth being precise about what's per-user and what's shared here. We can put rules under the .cursor/rules directory with the .mdc extension and they're actually versioned (as the official docs say), and it's a good practice to commit them so everybody can benefit from them.

But there's also the AGENTS.md file which is picked up by Cursor if it's in the root of the repository or in any nested directory, so if we have an agent working in such a directory it gets the configuration defined in that file.

Similar for .cursor/mcp.json and .cursor/hooks.json files.

The same goes for skills which we can place under .cursor/skills or .agents/skills directories; as per the docs it also reads .claude/skills and .codex/skills as compatibility directories, because Claude and Codex put skills there.

What's more, there's this "trust" thing in the Cursor CLI, it has a --trust flag which is supposed to trust the workspace you're working on without asking — this suggests that if we were to clone a fresh repository it wouldn't be trusted and the configuration which is already there would do nothing until each person clears that.

And then… even if we create a rule it doesn't mean that it will actually run — there are four rule types and only alwaysApply: true is unconditional, the others need to meet some other conditions:

  • it must match a file path using a glob pattern

  • the agent must think that the description of this rule is relevant

  • you have to @-mention the rule explicitly

That means that the shared convention defined in the rule using a glob won't apply until somebody opens a file which matches this glob. And then "why did it ignore our convention" is a very hard question to answer. For example:

YAML
---
alwaysApply: true
---

It's good to keep either team-wide standards in always-apply rules or in the AGENTS.md file, and per-directory conventions in globbed rules (but we'd say we should use them for guidance which is specific only to a particular area of the repository).

In the Team and Enterprise plans you can also manage rules centrally from the Cursor dashboard — it's the real way to enforce a configuration, and it's gated on the plan, not on what a developer thinks the repo needs.

In Antigravity CLI

Defining what is shared and what is per-user on this harness.

What's shareable (in the repo):

  • Either of these files, at the root of the project:

    • GEMINI.md

    • AGENTS.md

  • Skills defined in the .agents/skills/ folder

What's per-user: all the other configuration stuff that the CLI settings docs cover, stored as a regular JSON file at ~/.gemini/antigravity-cli/settings.json. That page describes no project-level settings file to commit next to it.

Which means that if another person joins on the same harness they will have your notes and skills but their own permission settings (for example they'll have their own allowNonWorkspaceAccess setting which is responsible for letting the agent read and write files outside of project folders and is off by default unless they turn it on).

Also, the above-mentioned folder is called .gemini/skills/ in some projects so you need to either move or rename it to .agents/skills/ for it to be detected by the agent (we could say that in a cross-tool world this path is the same as the one you'd pick anyway, and the official docs say to use .agents/skills/, so we're not losing anything here).

In theory you can choose either GEMINI.md or AGENTS.md here. But we'd recommend AGENTS.md as this file is also being read by Codex, Copilot CLI, Cursor and Kimi Code; in the docs the workspace file is described as one or the other, so you can have both but then you'll need to update both whenever you want to change sth and there's no information which one is preferred.

In Kimi Code CLI

If you want to make the information available across the entire project, create AGENTS.md at the top level of the repository (or .kimi-code/AGENTS.md, if you want to keep it only for Kimi). Skills go in one of these locations:

  • .kimi-code/skills or

  • .agents/skills

Personally, we would go with the second one as then you have a single folder which is read by every harness except Claude Code. So it's five.

In case of general instructions for yourself, you can create AGENTS.md in your $HOME/.kimi-code directory (or in $KIMI_CODE_HOME if you've changed it). Or, if you want to have some specific instructions for multiple tools, you can create AGENTS.md in $HOME/.agents.

But… There's one thing to be aware of. The docs describe how to define hooks only via the [[hooks]] section of the user-level config.toml file — there's no such thing for the repo level. That means that on this harness, we can't attach a gate to a PR so your teammates can benefit from it. It must go to CI. Which makes it the clearest case in the whole set for the tier split: put the facts in the repository and the enforcement where the repository can reach every developer.

There's also kimi doctor, and it's worth reading what it actually checked. Ours printed one OK line per file:

CONSOLE
$ kimi doctor
Kimi doctor

OK config.toml  /Users/you/.kimi-code/config.toml
OK tui.toml     /Users/you/.kimi-code/tui.toml

All checked config files are valid.

Both of those live under ~/.kimi-code, which means that it's a per-machine check rather than a repo-level one.

And before you invite a teammate to this project, ask them to run kimi --version. The rebuilt CLI reports 0.31.x and stores its data in the $HOME/.kimi-code directory by default. There's also an older program called kimi-cli — the one the kimi migrate command imports data from — and everything above assumes the former.

What you are actually aiming for

It's not about uniformity — you can't enforce it if you don't have a mandate, and somebody showing up with an unconfigured harness isn't a problem. It's about:

  • Facts loaded, whatever they were driving

  • The gate that really matters being in CI, where nobody can turn it off

  • Nothing assuming a single tool

  • And space for everybody to keep their own settings

Unless you really need sth — a path that must never be read, or some compliance requirement — then stop here and deploy managed settings, because that's what they're there for.

But the most expensive mistake is this middle ground — a rule everybody says is important but put in a file any of these tools can ignore.

j / k to move between lessons