# Notes for Harness Implementers

> For AI agents: a documentation index is available at /llms.txt — markdown versions of all pages are available by appending index.md to any URL path.

This page is for people building or maintaining a platform that loads Agent Skills. It is not a specification; the [Agent Skills specification](https://agentskills.io/specification) and the [client implementation guide](https://agentskills.io/client-implementation/adding-skills-support) are. It is a list of the places where four tested implementations diverge from those documents or from each other in ways that break skill portability, with the behavior that would narrow each gap. Each platform report opens with a spec alignment summary for that platform. This guidance is derived from the automated findings in the [platform comparison](https://agentskillimplementation.com/platforms/) (check list 0.4, tested in headless mode against Antigravity CLI 1.2.11, Claude Code 2.1.274, Codex CLI 0.157.0, and GitHub Copilot CLI 1.0.88; each platform report lists the releases behind its findings). Untested platforms may behave differently, so this guidance is likely to change as we study more harness skill implementations. The terms used here (push harness, pull harness, canary phrase, and more) are defined in the [glossary](https://agentskillimplementation.com/guidance/glossary/).

## Where implementations contradict the specification

**Resolve skill-relative paths against the skill directory, or tell the model where that directory is.** The spec tells authors to reference bundled files with paths relative to the skill root, but on Antigravity, Claude Code, and Copilot CLI a bare `references/setup-guide.md` fails when used from the working directory, and recovery is the model's, not the platform's. On Codex the model qualified every path itself, so the platform's base went unexercised (`path-resolution-base`). Claude Code and Copilot CLI now state the skill's base directory at the top of the injected content, which gives the model the anchor it needs; Codex's listing carries only an aliased location, and Antigravity's injection cannot be observed (`activation-location-disclosure`). Stating the base directory is the cheaper fix; resolving relative paths for the model is the complete one.

**Decide what "load the entire file" means for frontmatter, and document it.** The spec says the agent loads the whole SKILL.md at activation; Claude Code and Copilot CLI strip the frontmatter and inject only the body, and their listings carry name and description only, so `compatibility` and `metadata` never reach the model through any platform channel (`frontmatter-handling`, `discovery-listing-fields`). Either surface those fields somewhere the model can see them or state plainly that they are for humans and tooling.

**Count the description limit in code points.** The spec's reference validator counts Unicode code points; Codex matches it and Copilot CLI counts UTF-16 code units, so the same description passes one and is dropped by the other (`description-length-unit`). Dropping a skill for an over-limit description, as Copilot CLI does, is also the harshest of the observed postures; truncation or a warning keeps the skill usable. Names have the same problem twice over: the spec allows "unicode lowercase alphanumeric characters" with an ASCII parenthetical, and its reference validator accepts any Unicode alphanumeric and counts code points. Codex matches that reading; Copilot CLI rejects every non-ASCII name; Claude Code and Antigravity enforce no cap. Whichever reading a platform takes, a rejected name should produce a diagnostic, and the spec would benefit from choosing one (`name-length-unit`).

**Treat bundled scripts as a permission design problem.** The spec presents `scripts/` as code the agent can run. Under the platform's default headless posture, the script ran on Codex and Antigravity and was blocked on Claude Code and Copilot CLI, and the experimental `allowed-tools` field changed nothing under any spelling (`bundled-script-execution`, `allowed-tools-behavior`, `allowed-tools-name-matching`). If the field is to mean anything, its tool-name vocabulary has to be published; if not, a visible denial with a hint about how to approve is the best outcome the tests saw.

## Where implementations contradict each other

**Follow the guide's project-over-user precedence, and warn on collisions.** The implementation guide calls project-over-user a universal convention. Antigravity and Copilot CLI follow it, Claude Code resolves user-over-project, and Codex lists both entries and leaves the choice to the model. No platform warns (`name-collision-precedence`). The same applies to the same name under two roots of one project, where Copilot CLI deduplicates native-first, Codex lists both, and Claude Code and Antigravity read only their native root (`multi-root-collision-precedence`).

**Scan the cross-client convention path.** `.agents/skills/` is read by Codex and Copilot CLI and is Antigravity's native root, but Claude Code does not scan it, so a skill installed there for portability is invisible on one of four platforms (`cross-client-directory-interop`).

**Scan recursively, but stop at a skill boundary.** Codex and Copilot CLI find skills in grouping folders while Claude Code and Antigravity see direct children only (`recursive-root-discovery`). Codex alone continues into a discovered skill's own tree and registers a SKILL.md found in its `references/` as a separate skill; Copilot CLI stops descending once it finds one (`nested-skill-discovery`). The Copilot CLI behavior is the one that lets authors ship examples safely.

**Pick one identity for a skill whose name and directory disagree.** Three platforms activate by frontmatter name and Claude Code by directory name, and two of the three list both strings because their listing paths carry the directory (`name-directory-mismatch`). Either is defensible; rejecting the mismatch with an error would be better than either, since the spec requires the two to match.

**Be consistent about spec-invalid input.** Malformed YAML is tolerated by Codex and Claude Code and rejected by the Antigravity and Copilot CLI catalogs; a missing description is tolerated everywhere except Codex; over-long names are rejected by Codex and Copilot CLI only (`malformed-yaml-tolerance`, `missing-description-handling`, `invalid-name-tolerance`). Whichever posture a platform picks, a rejected skill should produce a visible diagnostic; none of the tested platforms reports why a skill is absent from its catalog.

## Choices that shape the token cost

**Deduplicate reactivation platform-side, and invalidate on file change.** Claude Code and Copilot CLI re-inject the full body every time a skill is activated in a session (`reactivation-deduplication`). On Codex the model deduplicated by itself, reusing its in-context copy, and thereby missed a mid-session edit in every run (`reactivation-freshness`). A platform that acknowledges the earlier copy when the file is unchanged, and re-delivers when it changed, gets both the saving and the freshness.

**If you enumerate bundled files, cap it and publish the exclusions.** Copilot CLI is the only tested platform that lists a skill's files at activation; it listed 42 of 43 files in a deliberately bloated fixture, dotfiles and binaries included, and omitted only a `vendor/` tree (`bundled-file-enumeration-scale`, `resource-enumeration-behavior`). The list is useful, and authors need to know what it will and will not include. On real catalogs the median skill's list runs 50 to 370 tokens per activation and the tail passes 10,000, re-sent on every reactivation ([the audit](https://agentskillimplementation.com/guidance/enumeration-cost/)).
