Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Spec Migration

ASecurity

Decide whether a change to the spec format needs a migration, and write it so `agnostic-ai migrate` rewrites old specs safely. Use when a change renames, replaces, deprecates, removes, or tightens any field users write under .agnostic-ai/ or in agnostic-ai.yaml.

22 stars
0 votes
0 copies
0 views
Added 10/4/2026
ai-agentsgo

Works with

cli

Security Analysis

A100/100

Scanned 10/5/2026

$npx -y skills add Chemaclass/agnostic-ai --skill spec-migration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Spec Migration?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Spec Migration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chemaclass-spec-migration/badge)](https://www.skillsdirectory.com/skills/chemaclass-spec-migration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: spec-migration
description: Decide whether a change to the spec format needs a migration, and write it so `agnostic-ai migrate` rewrites old specs safely. Use when a change renames, replaces, deprecates, removes, or tightens any field users write under .agnostic-ai/ or in agnostic-ai.yaml.
---

# spec-migration

A spec migration rewrites a user's old spec form into the new one without changing what sync writes. `agnostic-ai migrate` runs every pending migration from one registry, `specMigrations` in `internal/cli/migrate.go` (#1755). Users should never have to rewrite specs by hand after an upgrade.

## When a change needs one

Ask this for every change to a spec kind, a frontmatter field, a YAML key, or `agnostic-ai.yaml`:

| The change | What to ship |
| --- | --- |
| Renames a field, or adds a new form that some or all entries map to one to one | A migration and a lint warning on the old form; the old form stays accepted |
| Deprecates a form that no entry maps to one to one | No migration: a lint warning that explains the manual rewrite |
| Adds a new optional field | Nothing |
| Rejects specs that used to load, where a rewrite that keeps their meaning makes them load again | A migration, plus a lint warning at least one release before the rejection |
| Changes a form's meaning or default | Not a migration: a behavior change with a CHANGELOG entry and a lint warning at least one release ahead |
| Removes a form | Only in a breaking release, after its migration shipped, no earlier than the migration's issue allows |
| A style preference with no change in meaning or output | Nothing, or a lint note. Never a migration |

While the project is 0.x, a breaking release is a minor release whose CHANGELOG has a breaking section.

## Rules

1. **Output stays the same.** `sync`, then `migrate`, then `sync --check` exits 0 for every target the spec already reached. The only exceptions are the ones the migration's issue names, such as a spec reaching new targets (which `sync` then lists) or a literal secret becoming a reference. Any other change to a synced file is not a migration.
2. **Old form keeps working until its removal release.** That release replaces it with an error that names the migration to run with the last version that has it. The migration and its fixture stay until then.
3. **Idempotent and stateless.** A migration detects its own old form. Running it twice changes nothing. The release it records is metadata only.
4. **Map one to one or skip.** Entries that do not map stay as written with a one-line reason that `migrate` reports. A spec that sets both the old and the new form is a skip, never a merge.
5. **Touch only what you own.** Edit through the shared editor in `internal/cli/migrate_yaml.go`: `rewriteTopLevelYAMLKeys` for a YAML spec, `rewriteFrontmatterKeys` for Markdown frontmatter. Comments, key order, quoting, and bodies stay as written. The registry writes atomically and keeps the file mode.
6. **Never expose a secret.** Diffs, skip reasons, and errors show values of `env`, `headers`, URLs, and args as references or `<redacted>`; `redactMigrationLines` does this for every migration. A migration never turns a reference into a literal and never moves a value into another file or into the global home.
7. **Stay inside the spec roots.** The registry resolves each change's real path. A file outside the project, `local/`, or global spec roots, such as a pack or a symlink into one, becomes a skip that names the pack. Skip a pack layer's entry in `Plan` with `packSkip`.
8. **Import writes the new form.** A project that starts after the change never needs the migration.

## Steps

1. Name the migration `<group>-<what>`, where `<group>` is the name `migrate --only` takes, such as `hooks-portable-events`. Record the next release version, the one the CHANGELOG's Unreleased section will become, as the one that adds it.
2. Write the fixture first, as a project under `internal/cli/testdata/migrate/<id>/`, and as a global home under `internal/cli/testdata/migrate-global/<id>/`: old-form specs with comments and odd formatting, both-forms and unmappable cases, and the expected rewrite. Use placeholder values such as `${TOKEN}` or `REDACTED`, never a real credential. Set `ProjectOnly` instead of a global fixture only when the global home never had the old form.
3. Implement `Plan` in `internal/cli/migrate_<what>.go`: it reads the `migrationScope` (a project, or the global home with `global` set) and returns changes plus skip reasons, and never writes. Add it to `specMigrations` in release order.
4. Add or update the lint warning for the old form, pointing at `agnostic-ai migrate`.
5. Run `go test ./internal/cli -run Migrate`. The shared tests run `sync`, `migrate`, and `sync --check` on every registered migration's fixtures, project and global, then plan again to prove idempotence.
6. Make `import` write the new form.
7. Document the new form first on its spec-format page, keep the old form there as an alias, and add a CHANGELOG line that says "run `agnostic-ai migrate`".
8. In the PR body, state the migration ID, what it rewrites, what it skips, and the earliest release that may remove the old form.

## When the editor falls short

The shared editor renames a top-level key and sets a one-line scalar value. A migration that needs more, such as rewriting a list, extends the editor in `migrate_yaml.go` with a test that keeps every other byte, rather than editing text by hand in `Plan`.

Attribution

ChemaclassChemaclass
View sourceSee grades on GitHubMore from Chemaclass →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698461 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →