Field notes

An installed skill is a dependency. Open source is how you pin it.

A skill copied from another repository is a dependency nobody versioned. Open-source Kortix pins each skill to a hash and a grant in a repo you own.

The Kortix Team
Kortix··6 min read

Your agent answers the same question differently this month and nobody edited a prompt. Somewhere in its skills folder is a SKILL.md copied from another repository, and nothing in your project records which revision of it the agent read this morning. That is a dependency without a version, and why a good week can turn into a bad one with no commit to blame. Kortix is the open-source AI Operating System: your agents, their skills, your company memory, and every connector in one git repo you own, with the agents working on real cloud computers.

A skill is a folder with a trigger in its frontmatter

A skill is a folder holding a SKILL.md plus whatever scripts and reference files it needs (Anthropic). The name field runs 1 to 64 characters, lowercase letters, digits and hyphens, and has to match the parent folder. description runs to 1,024 characters and should say both what the skill does and when to use it (specification).

That description is the routing key: all an agent reads before deciding whether to open the rest, so its wording decides when the skill runs. The Claude documentation says it plainly: "The description is what Claude matches your request against when determining whether to trigger the Skill, so it must say both what the Skill does and when to use it" (overview). Kortix's docs put the same rule in one line: "description is what the agent reads to decide when to load the skill. Write when to use it, not only what it is" (agents).

The name and description cost "~100 tokens per Skill" at startup. The body loads only when the skill triggers, at "Under 5k tokens", and bundled files cost nothing until an agent opens one (overview). A lockfile entry costs no context at all.

The same name, different bytes

Copying the folder in is the whole install step, which makes the change invisible. The file keeps its name and no version gets bumped, because the standard requires a name and a description and neither carries a version.

Two skills of the same name cannot both load. The first skill of a name wins, in a fixed order: the managed kortix-* skills, then skills/, then .kortix/opencode/skills/. A managed skill overwrites a project copy of the same name, and a dozen of them are copied into every session (Kortix docs).

A colleague drops a newer router into skills/, its description a little broader than the one it replaced. The agent now loads that router for messages it used to send straight to a person. Everyone reads it as the model getting worse. It was a file change nobody reviewed, in a folder nobody diffs.

What a lockfile records

Kortix's repository pins the skills it borrows in a skills-lock.json at the root, one entry per skill (lockfile). Six entries sit beside 31 skill folders under .agents/skills/, the folder kortix init links to a local checkout's coding tools. Most of what those agents read was written here. Six names were borrowed. One entry, verbatim:

    "ponytail": {
      "source": "DietrichGebert/ponytail",
      "ref": "v4.10.0",
      "sourceType": "github",
      "skillPath": "skills/ponytail/SKILL.md",
      "computedHash": "210fa0831f649ce9f8a305f7b7c8cf2a0dd09ac4dd53067109941b96e7811d4e"
    },

Four fields do the work. source names the repository. sourceType says what kind of address that is, and skillPath names the file inside it. The 64-character computedHash fixes the bytes. The ref of v4.10.0 pins a tag as well, so the entry records the release the team reviewed and the text it contained.

A hash that no longer matches means the file changed after the pin was written. That is what the hash buys: it turns a sentence about which router the agent loads into a statement of which text it loads. When the hash moves, the review looks like any dependency review. Read the new text, run the script once by hand, and write the new hash in the same commit that needed it.

Three shapes a reviewable skill takes

Three skills there show what makes a good one, in three shapes, all procedures rather than topic notes.

A ladder that stops at the first rung. ponytail forces the smallest solution that works. Its whole method is an ordered list: "Stop at the first rung that holds". The first rung asks the question most agents skip, "Does this need to exist at all?", and answers it: "Speculative need = skip it, say so in one line. (YAGNI)". Rung five is where most of the saving happens: use a dependency that is already installed rather than adding one. A ladder with an order is checkable: a reviewer can point at the rung a session should have stopped on.

A stop condition written as a person's question. create-pr writes the title and body of a pull request for "a human who will not open the diff". Its done test is that person's one question, and it says what to do with every line that does not serve it: "Cut a line that does not, even when it is true and took effort to find". It refuses the usual escape hatch too: "Delete a section that does not apply." Filling an inapplicable section with a placeholder is not an option either. The output is short because done is defined from the reviewer's side.

A rule a script enforces. testing opens with a prohibition: "During development, never run a full suite or a whole package's tests." The command itself enforces it: on a Mac a whole-package run is refused unless you name files or a test, "(exit 2, scripts/test-guard.mjs)". A rule that resolves to an exit code can be checked by someone who did not write it, and re-run by an agent that has never seen the repository.

That is the test for anything you install, whatever shape it takes: can a reviewer tell what done means?

A pin is not a grant

A hash says which revision you reviewed. It does not say whether an agent may load the skill.

Kortix keeps the second decision in kortix.yaml. The agent's skills grant compiles onto its permission.skill rule: a list allows each skill it names and denies every other skill. Where the grant is set, it replaces any permission.skill rule in the agent file (Kortix docs). The docs' own agent, shortened to the grants:

kortix_version: 2
default_agent: support
agents:
  support:
    file: agents/support.md
    skills: [kortix-cli, triage]

Two names open, everything else closed. A skill can sit in the repository, reviewed and unchanged, and that agent still cannot load it. A folder on disk is not access. Running a script by path is a tool rule rather than a skill rule, so a guard script can run while the skill that explains it stays closed.

The two decisions fail differently, which is why both belong in one review. A stale hash is drift you can see. A missing grant is a door nobody notices until an agent answers as if it never had the skill.

When a skill belongs in your repo

Copy the folder in and edit it when your version differs from upstream on purpose, when its steps sit on your release path, or when it ships a script you run. Pin it and follow its releases when it comes from a project you do not change: the hash tells you when it moved, the diff what moved. Leave out the skill you can neither edit nor pin, however well its description reads.

In Kortix both decisions land in one diff. Skills sit beside the agents that load them, the grant is a line in kortix.yaml, and the lockfile records which revision each name means. Session work reaches main through a change request, and merge is default-deny for agents. The reviewer opening that request sees the text, the grant and the hash together. Which text the agent loaded this morning is recorded in a repository a colleague can read.

Next reads: Kortix vs Hermes makes the review-gate case for a personal agent that stages its own skill writes, and The repo that holds the whole company the case for one repository.

Start with one skill your team runs by hand. Copy the folder, add its name to the grant, pin it, and let the first change to it arrive as a diff. Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free. Try Kortix

Run your whole company from one repo you own.

Start with one job and grow from there.

Get started