Skip to content

Same Version, Different File: Rebase a Drifted Claude Code Skill

Adityo Guni Waluyo

A local skill and its upstream both said 2.2.1, but the contents had long diverged. How to rebase a skill without inheriting the drift.

TL;DR

A matching version number hid a rewritten SKILL.md with inverted security doctrine. Rebased the file byte-identical to upstream, moving local rules into references docs and a wrapper script. Lesson: never trust frontmatter versions, byte-compare against upstream, and layer customizations on top.

Same version, different file

That morning I opened skills/autonomous-ai-agents/claude-code/SKILL.md in my Hermes config repo, looking for the delegation doctrine I usually keep there. What I found was the opposite. In that local copy, --dangerously-skip-permissions read like a routine option, safe to reach for any time. Upstream reserves the flag for isolated environments only, and its warning dialog deliberately defaults to "No, exit" [1]. The security doctrine was inverted, in my own production setup.

I checked the frontmatter. Version 2.2.1. Upstream also said 2.2.1. My first reasoning was simple: same version number, so same content, probably a trivial formatting difference. A byte-per-byte comparison against the raw upstream file proved me wrong. The local copy had been rewritten well past recognition while the upstream SKILL.md runs about 754 lines. The version number in a skill's frontmatter is not an authenticity indicator. Anyone who copies and edits the file can forget to bump that number, and nothing sounds an alarm. It also lives in its own namespace: the Hermes release version, the skill frontmatter version, and the Claude Code CLI version are three different things, and treating any of them as proof of file integrity is the trap that nearly got me.

Why editing in place is the trap

The skill format is designed so nothing has to be force-edited. A skill is a folder with a minimal SKILL.md carrying a name and description, plus optional references/, scripts/, or assets/ folders [3]. Agents load it through progressive disclosure: discovery reads only the name and description, activation pulls in the full instructions when the task matches, execution runs bundled scripts or reads companion files on demand. Claude Code follows the same open standard [2]. Local doctrine therefore has a natural home one layer up, without ever touching the skill's core.

That is how this rebase was done. SKILL.md went back byte-identical to the upstream file. All project-specific delegation doctrine moved into references/delegation-workflow.md: the prompt enhancement gate, per-task tool whitelists, a permanent ban on git commit and push. The execution path is scripts/cc-delegate.sh, a wrapper that invokes the CLI in print mode -p, one shot without interactive dialogs [4]. No bypass flag in the wrapper, matching upstream's strict posture on permissions.

Hermes itself already anticipates forks like the one I had. When it syncs bundled skills, Hermes records an origin hash per skill in .bundled_manifest. On the next update, a local copy whose content changed counts as user-modified and is skipped forever, so your edits never get silently overwritten [5]. The protection is great for keeping edits and terrible when the edit should never have existed. As long as the local SKILL.md differs from upstream, every upstream release has to be reviewed by hand, and that is exactly where a security drift like an inverted bypass doctrine can survive unnoticed for months.

Layering on top of upstream

The rebase went cleanly because there was nothing to merge. The skill core returned to the author's original, and the local doctrine moved up a layer where its status as a local addition is explicit. The benefit shows up on the next update: the upstream diff just gets pulled, with no conflict to adjudicate line by line. Compare that with the fork scenario, where every upstream release forces you to re-read hundreds of lines to decide what survives, and the security review is usually the first casualty.

The pattern is easy to replicate. Project-specific rules go into references/ as companion documents. Automation that needs to execute goes into scripts/ as a wrapper calling upstream's standard interface instead of replacing it. The only discipline to keep: if you find yourself editing SKILL.md, the layering design is wrong, not the skill.

One lesson came home with me. If a local file and its upstream show the same version number, do not trust it; byte-compare against the raw file, every time. And when you need to add rules, put them in a top layer through references/ or a wrapper script. The upstream core stays intact, the next update pulls without drama, and your security doctrine cannot quietly invert itself without someone noticing.

Sources

  1. SKILL.md: claude-code, Hermes Agent upstream
  2. Extend Claude with skills (Claude Code Docs)
  3. Agent Skills Overview
  4. CLI reference (Claude Code Docs)
  5. Skills System (Hermes Agent Docs)

Related articles