How to version control AI agent skills
By Randy Olson, Co-Founder & CTO, Goodeye
Keep agent skills in a git repo. It versions them properly, reviews them properly, and costs nothing. It breaks in three specific places once a second person has a clone: the clone is only as current as the last pull, the clone cannot be taken back, and the check that decides whether the output is acceptable is usually not in the repo at all. Goodeye is built for those three.
Most teams keep their agent skills in a git repo. That is the right call: full history, real code review, pinning that works exactly as well as the machinery you build around it, free, already installed. This page is not going to talk you out of it. It breaks in three specific places, and all three appear the moment a second person has a clone.
How do you version control agent skills with git?
One directory per skill, each with a SKILL.md:
skills/
high-signal-chart/
SKILL.md
reference.md
incident-writeup/
SKILL.md
Commit it. Tag a release, or pin the directory into consumer repos as a submodule. Then sync it into whatever directory your agent reads:
ln -s "$PWD/skills" ~/.claude/skills
That is a good setup. It diffs cleanly because a skill is markdown, and a change to a skill goes through the same pull request as a change to the code it describes. If you are one person, or a team whose skills never leave one repo, you can stop reading here.
Why does a teammate end up running a different version?
The usual answer, "git versions the file, not what's running," is wrong. Git versions exactly what you pin.
The failure is behavioural. Pinning is dependency machinery, and almost nobody builds dependency machinery for a folder of markdown. In practice the skills directory is cloned once and pulled when somebody remembers, so a teammate who cloned three weeks ago is three weeks behind, and neither of you finds out until their agent produces something yours would not have.
Pin it properly and you have a different problem: everyone is on the version you pinned, not the version that is current, and moving the pin is a commit in every consumer repo. Right when skills change quarterly, wrong when a skill changes because somebody learned something on Tuesday. Notion sidesteps this by having no versions at all, so the agent gets whatever the last editor left.
In Goodeye the hosted skill is the source of truth, so there is no pin to move. Machines mirroring it pull automatically, at least hourly, and an agent on MCP or REST gets the current version on its next fetch.
Two limits worth knowing. That pull rides along after a goodeye command completes, so a teammate who never runs the CLI never updates, and it is suppressed in CI on purpose. And it never overwrites a file you edited locally: your edit is preserved, the drift is reported to you rather than to the owner, and a teammate who edits their copy has quietly forked it.
Can you revoke an agent skill you already shared?
No distributed copy is revocable, and that includes Goodeye's.
A contractor who cloned your repo has your skills, and revoking repo access does nothing about the clone. If they synced a Goodeye skill to ~/.claude/skills, that file is on their laptop and stays there: the automatic pull is deliberately report-only and never removes a local directory. Anyone who runs cp -r defeats every mechanism on every side of this comparison. Notion is the same story with worse ergonomics, since sharing is a per-page permission somebody has to remember to remove and no single command lists who currently has it.
What revoking a Goodeye grant does take back is everything hosted:
goodeye skills revoke high-signal-chart alice@example.com
She loses read access, stops receiving every future version, and loses the ability to run the semantic verifiers the skill names, because a skill grant cascades to the verifier grants underneath it. Her copy of the runbook is hers forever. Her ability to prove the output met your standard is not.
Does the check that decides whether the output is good travel with the skill?
You can commit a judge prompt next to SKILL.md, and plenty of teams do. It travels perfectly, because it is text in the same repo.
Three things a committed prompt does not get you. You cannot improve the check without every consumer re-pulling, where a Goodeye verifier is a separately deployed artifact with immutable versions. Two people's runs are not comparable, because a committed prompt runs against whatever model that person had configured, where a verifier pins its judge model and carries labeled examples that calibrate it. And the right to run it does not die with the grant.
One precision, because it changes what is actually worth moving: only semantic verifiers are hosted objects, the interpretive ones covering tone, policy adherence, whether a claim is supported. Structural and functional checks, the ones covering format, required fields, tests, and numeric bounds, live inline in the skill body and travel as text. Git handles those exactly as well. The differentiated object is the judged check, not every check. Running one draws on the runner's own credit, so a grantee needs an account.
What you would build to get this in git
Not an argument that git is bad. A shopping list, worth pricing before you decide:
- A submodule or lockfile pinning the skills directory, plus a bump commit in every consumer repo whenever a skill changes.
- A sync step landing the skills in each agent's directory on each machine.
- Something that tells people they are behind, since
git pulldoes not run itself. - A home for the judge prompt, a decision about which model runs it, and labeled examples so two people's runs mean the same thing.
- A way to keep that prompt in step with the skill it grades.
- An answer for the contractor who left last month, whose clone still passes every check you have.
One through five are a weekend and then permanent maintenance. Six has no answer in git, because the check is text in a repo they already cloned.
git vs Notion vs Goodeye
When a git repo is the right answer
Four cases, none of them edge cases.
The skill is reviewed by the people who review the code. A pull request on a skill diff is a real approval gate, and Goodeye has none: it has optimistic concurrency on save, which stops two people clobbering each other but holds nothing pending a sign-off. If a skill must not change without a second pair of eyes, git does that today and Goodeye does not.
Budget is zero and stays zero. Git is free and installed; semantic verifier runs are metered. Your teammate should not need another account, and every Goodeye grantee needs one.
And if your team is disciplined about pinning and pulling, git already solves version drift, which leaves one problem out of three: the check that does not travel.
Notion and Google Docs
Notion is good at what it was built for, a runbook a person reads, with comments, somewhere non-engineers will open it. The moment an agent loads it, three things go missing: no addressable version to pin, no machine-readable contract, and access nobody audits. If your skills live there today the migration is small, because the skill is already markdown-shaped.
Keep authoring wherever you author. If skills sit next to the code they describe and change on the same pull requests, git is the answer. If they are shared with people outside the repo, if a teammate has been on a stale copy without knowing, or if the rubric that decides whether the output is good has drifted from the skill it grades, those are the three things Goodeye is built for.
Related: Share an AI agent skill privately and revoke access · Use the same agent skill in Claude Code, Cursor, and Codex · Who owns an agent skill when someone leaves
The right default, and the only one of the three with real code review on a change. Full history, and pinning that works exactly as well as the machinery you build around it: a tag, a submodule, a lockfile, a CI install step. Free, already installed, and no second account for a teammate. Breaks on distribution rather than on versioning: a clone is only as current as the last pull, a clone cannot be taken back, and nothing in the repo runs the check that decides whether the agent's output was acceptable unless you build that too.
Fine for a runbook a human reads, and the wrong shape the moment an agent loads it. There is no addressable version to pin, so an agent gets whatever the last editor left. Access is a per-page permission somebody has to remember to set and remember to remove, and there is no single command that lists who currently has it. No machine-readable contract, no check on output. Teams usually land here because the skill started as a doc for people and quietly became a doc for agents.
- 03
Goodeye
A private home for the skills your AI follows and the verifiers its work must pass. The hosted skill is the source of truth and mirrors into whatever directory your agent reads, so machines pull the current version automatically rather than when someone remembers. Grants are per person or per team at view, edit, or admin, and the verifiers a skill names are granted with it. Revoking a grant ends hosted access and stops the verifiers running. No approval workflow before a change lands, which is the one thing a git pull request does better.
Frequently asked questions
Can't I just use git submodules for agent skills?
Yes, and it works. A submodule pins the skills directory to an exact commit, so every consumer repo gets the version you pinned and nothing moves under them. The cost is that the pin is now a dependency you maintain: moving it is a commit in every consumer repo, and until you do, everyone is running the version you pinned rather than the version that is current. That trade is right when skills change quarterly and wrong when they change weekly. Goodeye inverts it: the hosted skill is the source of truth, and machines pull the current version automatically rather than waiting for someone to bump a pin.
What about publishing agent skills as a private npm package?
It gives you real versioning, semver ranges, and an install step your CI already understands, and for a team that ships JavaScript it is a fair answer. Two things it does not give you. Revocation is still not possible, because an installed package is a copy on disk like any other. And npm has no concept of the check that decides whether the agent's output was acceptable, so the rubric still lives somewhere else and still drifts out of step with the skill. Goodeye grants the skill and the verifiers it names together, and a revoked grantee loses the ability to run those verifiers.
How do I know which version of a skill a teammate is running?
In git, Notion, and Goodeye alike, you cannot see this from your own machine. There is no owner-side roster of who is on which version in any of the three. What Goodeye gives the person on the other end is goodeye skills sync status, which reports each mirrored skill as clean, modified-local, behind-server, conflict, deleted-on-server, or untracked. That is a self-serve answer on their machine, not a dashboard on yours. If you need an owner-side view of who has access, goodeye skills grants lists current grants, though it lists grants rather than people and it is not an access log.
Can I revoke an agent skill I already shared?
Not the bytes, in any system. A markdown file someone has already synced is a file on their machine, and no product can reach onto a laptop and delete it. Goodeye included: its automatic pull is deliberately report-only and never removes a local directory. What revoking a Goodeye grant does take back is everything hosted. The teammate loses read access to the skill, stops receiving every future version of it, and loses the ability to run the semantic verifiers the skill names, because revoking a skill grant cascades to the verifier grants underneath it. Their copy goes stale and stops passing your checks.
Do I have to stop keeping agent skills in git?
No. Keep authoring wherever you author. A skill is a markdown file, and git is a good place to write and review one, particularly when the skill sits next to the code it describes and the same people review both. The question this page is about is not where you write the skill, it is what distributes it and what checks its output. Goodeye is a distribution and verification layer, not an editor, and plenty of teams commit a skill to git and publish it to Goodeye from the same directory.