RFD 0007: Plugin migration from v1 skills¶
Summary¶
v1 ships 78 skills (21 language guides, 30 framework guides, 19 Samuel-original workflows, 7 Anthropic community workflows, 1 commit-message) embedded in the framework binary. v2 migrates them to per-plugin Git repos under github.com/samuelpkg/samuel-*, indexed by a separate samuel-registry repo, with a samuel-starter meta-plugin that auto-installs the 12 Samuel-Way workflows on samuel init.
The migration is mostly mechanical (scripted), with manual review for edge cases. Four skills become built-in v2 framework features instead of plugins (auto → ralph methodology; create-skill → samuel skill create command content; sync-claude-md + generate-agents-md → samuel sync command content). Two skills drop entirely (initialize-project and update-framework are replaced by samuel init and samuel update).
Plus: two translator plugins ship at v2.0 launch (claude-translator, codex-translator) to prove the agnostic-by-design story and validate the WASM plugin tier with real usage.
Problem statement¶
After [[0001|RFD 0001]] (plugin format), [[0003|RFD 0003]] (manifest schema + signing), and [[0005|RFD 0005]] (plugin loader), v2 has the mechanism to load plugins. What it lacks is plugins. samuel install go-guide would fail at v2.0 launch because no go-guide plugin exists.
v1's 78 skills represent significant accumulated content — language guides, framework patterns, workflow methodologies. Discarding them and asking the community to rewrite from scratch would lose months of work and break the v1 → v2 narrative.
The work is mechanical but high-volume:
- 78 skills → 78 plugin repos
- 1 registry repo with 85 entries (78 ports + 7 Anthropic community via
subpath) - 1 meta-plugin (
samuel-starter) depending on 12 of the 78 - 2 translator plugins (claude-translator, codex-translator)
- 1 reusable release workflow (consumed by every plugin repo)
= 83+ artifacts produced from one migration milestone.
Requirements¶
- Every v1 skill that survives ([[../../wiki/sources/2026-05-12-v1-skill-content-survey]]) has a corresponding v2 plugin at v2.0 launch.
- Plugin manifests are auto-generated from v1's SKILL.md frontmatter where possible.
- The migration is scriptable — running it twice produces the same output (idempotent).
- Each plugin repo has its own release workflow (using the reusable workflow from [[0003|RFD 0003]]) so updates flow naturally per-plugin.
- The registry's
index.tomlis the single source of truth for "which plugins exist and what's their latest version." samuel installresolves names against the registry transparently.- Smoke test passes: clean
samuel init→ starter pack installs 12 plugins → manually install go-guide + react + claude-translator → runsamuel run→ everything works.
Constraints¶
- The 78 plugin repos can't all be force-pushed in one operation — GitHub rate-limits API operations.
- Some v1 skills have
metadata.author: anthropicand live upstream atgithub.com/anthropics/skills. These are not forked; the registry references them bysubpath. - v2.0 must launch with both translator plugins functional, or the agnostic-by-design story is theoretical.
Background¶
v1 skill triage (recap from [[../../wiki/sources/2026-05-12-v1-skill-content-survey]])¶
Four buckets for the 78 skills:
-
Built into v2 framework (4):
autobecomes theralphmethodology in framework code;create-skillbecomes content of thesamuel skill createcommand;sync-claude-md+generate-agents-mdcollapse intosamuel sync(AGENTS.md-only per [[0002|RFD 0002]]). -
Starter-pack plugins (12): the Samuel-Way workflows that get auto-installed by
samuel init. Aggregated into thesamuel-startermeta-plugin. The list:create-rfd,create-prd,generate-tasks,code-review,commit-message,document-work,refactoring,security-audit,testing-strategy,troubleshooting,cleanup-project,dependency-update. -
Pure plugins (58): all language guides (21) + framework guides (30) + Anthropic community (7). Installable on demand. Not auto-installed.
-
Drop (2):
initialize-project(replaced bysamuel init);update-framework(replaced bysamuel update).
Plus two new plugins (not from v1): claude-translator (WASM) and codex-translator (WASM).
Why one repo per plugin¶
Three viable repository structures were considered ([[../../wiki/synthesis/v2-skill-migration-plan]]):
- One repo per plugin —
github.com/samuelpkg/samuel-go-guide,samuel-react, etc. - Monorepo with subpaths —
github.com/samuelpkg/samuel-plugins/<name>/. - Hybrid — official plugins in monorepo, community in own repos.
The user-confirmed decision (after weighing during wiki discussion) is Option 1 (one repo per plugin) with org github.com/ar4mirez/* initially. Reasons: standard ecosystem pattern (npm packages, cargo crates), per-plugin versioning + issues + PRs + release cadence, easier for community plugins to follow the pattern. Migration to a dedicated github.com/samuel-plugins/* org deferred for later if community grows.
Options considered¶
Option A: One repo per plugin, single org, migration script, reusable release workflow (chosen)¶
Bulk-create 78 repos under github.com/samuelpkg/samuel-* via a one-time migration script. Each repo uses the reusable release workflow from [[0003|RFD 0003]] for builds + signing. A separate samuel-registry repo with index.toml indexes them.
Pros: - Per-plugin versioning, issues, PRs, release notes. - Maps to standard ecosystem mental models (npm packages, cargo crates). - Plugin authors copy this pattern when writing their own plugins. - The registry is one small file, easy to audit and PR. - The reusable release workflow keeps each plugin repo's .github/workflows/release.yml to ~10 lines.
Cons: - 78 repos to bulk-create. GitHub API rate limits push back; needs sequencing. - 78 repos to maintain. Inactive ones accumulate. - Per-plugin CI minutes (small for public repos but non-zero).
Effort: 4-5 days (scripted migration). Plus a few hours of manual review on edge-case skills with non-standard frontmatter.
Option B: Monorepo with subpaths¶
All plugins live in github.com/samuelpkg/samuel-plugins/<plugin-name>/. One repo, many plugins.
Pros: - One place to PR multiple plugins at once. - Less repository bloat in the org. - Migration script is simpler (one repo init, populate, push).
Cons: - Versioning is awkward — one tag per plugin (go-guide-v1.0.0)? Tags per global release? Either is unconventional. - Per-plugin issues become labeled / projected onto a monorepo issue tracker. - Doesn't match how community plugins will be published (one repo each). - Migration to one-repo-per-plugin later is harder than starting that way.
Effort: Lower (one repo). But long-term cost is higher.
Option C: Hybrid — official plugins in monorepo, community in own repos¶
The 78 ports live in a monorepo; future community plugins live in their own repos.
Pros: - Compromise — easier migration, conventional community pattern.
Cons: - Two structures to support in the registry resolver. - Confusing for plugin authors: "Why is go-guide in a monorepo but my new plugin is its own repo?" - Cargo / npm / pip / Maven all use one-pattern-everywhere.
Effort: Same as Option B for migration; ongoing complexity for the registry.
Option D: No migration¶
Start v2 with no plugins. Let the community rebuild plugins as they need them.
Pros: - Zero migration work. - v2 launches as a "pure" framework with no opinionated content.
Cons: - v2.0 launch is functional-but-empty. No language guides, no framework guides, no workflows. - Loses months of v1 content investment. - Community is small enough that "let the community rebuild" means "rebuilds happen slowly or never." - Breaks the v1 → v2 narrative ("here's the upgrade") into "here's a different product."
Effort: Zero migration; high opportunity cost.
Decision¶
Adopt Option A: one repo per plugin, single org (github.com/samuelpkg/samuel-*), scripted migration, reusable release workflow, separate samuel-registry repo.
The decision rests on three judgments:
-
The 78 SKILL.md files are real preservable value. Each one is high-quality, multi-paragraph content with concrete guardrails. Throwing them away would force users to rebuild — slow, error-prone, contrary to the v1 → v2 upgrade narrative.
-
One-repo-per-plugin matches ecosystem norms. Cargo, npm, pip, Maven all use it. Plugin authors writing the next plugin copy the pattern. Inconsistency (Option C) creates ongoing complexity.
-
The migration is mechanical and scriptable. 78 repos sounds like a lot, but the script handles 95% of cases identically. Manual review for the 5% takes hours, not days.
Implementation plan¶
Phase 1 — migration script (PRD 0005, days 1-2)¶
scripts/migrate-v1-skills.go — one-time tool, deleted after migration. Takes samuel_v1/.claude/skills/ as input, produces migration-output/samuel-<name>/ per skill.
For each skill directory:
- Parse SKILL.md frontmatter (YAML).
- Generate
samuel-plugin.toml: namefrom frontmatterversion = "1.0.0"(clean baseline at migration time)kind = "skill"(almost all v1 skills are pure text; the few withscripts/are still skills because they don't currently execute)samuel.framework = "^2.0.0"samuel.protocol = "^1.0.0"provides.skills = [name]capabilities.filesystem.read = ["/workspace"](default for pure-text skills)metadata.categoryfrom v1 frontmatter (language/framework/workflow)metadata.languageandmetadata.extensionsfrom v1 frontmatter (drives auto-load)metadata.descriptionfrom v1 frontmatter (first line of description)- Copy
SKILL.mdunchanged. - Copy
scripts/,references/,assets/if present. - Generate
README.mdfrom the manifest (description, install command, link to upstream). - Generate
LICENSE(MIT). - Generate
.github/workflows/release.ymlthat uses the reusable workflow from [[0003|RFD 0003]]. git init, commit, tagv1.0.0.
The script has a --dry-run mode that prints what would happen. Idempotent — re-running updates existing repos without failing.
Phase 2 — bulk repo creation + push (PRD 0005, day 3)¶
For each migration-output/samuel-<name>/:
- Create the GitHub repo via API:
gh repo create samuelpkg/samuel-<name> --public --description "<desc>". - Add the local repo as a remote:
git remote add origin git@github.com:samuelpkg/samuel-<name>.git. - Push:
git push -u origin main. - Push tag:
git push origin v1.0.0(triggers release workflow → cosign signing → GitHub release with signed artifacts).
Rate-limit: do this in batches of 10-15 with sleeps to avoid GitHub's secondary rate limits. ~30-45 minutes for all 76 (78 minus the 4 that became built-in minus the 2 dropped).
Phase 3 — registry repo (PRD 0005, day 4)¶
Create github.com/samuelpkg/samuel-registry:
samuel-registry/
├── index.toml # the canonical index
├── README.md
├── CONTRIBUTING.md # how to add a plugin to the registry
└── .github/workflows/validate.yml # CI: validate index.toml schema + resolve repos + check tags
The index.toml is generated from the migration script output. Schema per [[0001|RFD 0001]] and [[0003|RFD 0003]]:
schema_version = 1
[plugin.go-guide]
repo = "github.com/samuelpkg/samuel-go-guide"
latest = "1.0.0"
description = "Go language guardrails and patterns"
categories = ["language"]
tags = ["go", "golang", "guardrails"]
[plugin.react]
repo = "github.com/samuelpkg/samuel-react"
latest = "1.0.0"
description = "React 18+ framework guardrails"
categories = ["framework"]
tags = ["react", "typescript", "frontend"]
# Anthropic community plugins via subpath, tracking upstream main:
[plugin.mcp-builder]
repo = "github.com/anthropics/skills"
subpath = "mcp-builder"
latest = "main" # tracks upstream HEAD continuously
description = "MCP server development guide"
categories = ["workflow"]
upstream = true # signals: hands-off, don't expect signature
CI validates: schema parses, every repo URL is reachable (HTTP HEAD), every latest tag exists (git ls-remote --tags).
Registry updates: when a plugin releases a new version, a workflow in the plugin's repo opens a PR against samuel-registry/index.toml updating the latest field. Manual review for the first 6 months; consider automation later.
Phase 4 — starter-pack meta-plugin (PRD 0005, day 4)¶
Create github.com/samuelpkg/samuel-starter:
# samuel-plugin.toml
name = "samuel-starter"
version = "1.0.0"
kind = "meta" # special kind: no payload, just declares dependencies
[samuel]
framework = "^2.0.0"
[requires]
create-rfd = "^1.0.0"
create-prd = "^1.0.0"
generate-tasks = "^1.0.0"
code-review = "^1.0.0"
commit-message = "^1.0.0"
document-work = "^1.0.0"
refactoring = "^1.0.0"
security-audit = "^1.0.0"
testing-strategy = "^1.0.0"
troubleshooting = "^1.0.0"
cleanup-project = "^1.0.0"
dependency-update = "^1.0.0"
[metadata]
description = "The Samuel Way — twelve methodology workflows installed by default"
category = "starter"
samuel init installs samuel-starter by default, which transitively installs the 12 dependencies. samuel init --minimal skips. samuel init --without create-rfd,security-audit installs the starter but drops the two named plugins (the loader processes --without against meta-plugin [requires] before resolution).
Phase 5 — translator plugins (PRD 0005, days 5-6)¶
Two WASM plugins authored in TinyGo:
github.com/samuelpkg/samuel-claude-translator:
name = "claude-translator"
version = "1.0.0"
kind = "wasm"
[samuel]
framework = "^2.0.0"
protocol = "^1.0.0"
[provides]
hooks = ["sync.after", "init.after"]
[capabilities.filesystem]
read = ["/workspace"]
write = ["/workspace/**/CLAUDE.md", "/workspace/.claude/**"]
[wasm]
module = "plugin.wasm"
exports = ["init", "on_sync_after", "on_init_after", "health"]
[metadata]
description = "Mirror AGENTS.md to CLAUDE.md for Claude Code compatibility"
category = "translator"
target_tool = "claude-code"
The WASM module's on_sync_after hook reads every AGENTS.md the framework wrote, emits a sibling CLAUDE.md (verbatim copy). on_init_after installs a stub .claude/settings.json with PreToolUse hook scaffolding per [[../../wiki/concepts/claude-code-hooks]].
github.com/samuelpkg/samuel-codex-translator:
name = "codex-translator"
version = "1.0.0"
kind = "wasm"
[capabilities.filesystem]
read = ["/workspace"]
write = ["/workspace/**/AGENTS.md", "/workspace/.codex/**"]
[metadata]
description = "Emit Codex-specific files alongside AGENTS.md"
category = "translator"
target_tool = "codex"
The Codex-specific behavior depends on Codex's 2026 conventions. At minimum, it confirms AGENTS.md exists and emits .codex/config.toml if Codex uses one. Lighter than claude-translator because Codex aligns more closely with the AGENTS.md standard.
Both plugins are reference implementations for plugin authors writing translators for other tools (Cursor, Continue, Aider, etc.).
Phase 6 — smoke test (PRD 0005, day 7)¶
End-to-end in a clean directory:
$ samuel init my-test-project
✓ Installed samuel-starter (12 plugins)
✓ Created samuel.toml
✓ Created AGENTS.md (root + per-folder)
$ cd my-test-project
$ samuel install go-guide
✓ Installed go-guide v1.0.0
$ samuel install react
✓ Installed react v1.0.0
$ samuel install claude-translator
✓ Installed claude-translator v1.0.0 (WASM)
$ samuel sync
✓ Regenerated AGENTS.md (2 files)
✓ claude-translator: mirrored to CLAUDE.md (2 files)
$ samuel install codex-translator
✓ Installed codex-translator v1.0.0 (WASM)
$ samuel sync
✓ Regenerated AGENTS.md (2 files)
✓ claude-translator: mirrored to CLAUDE.md (2 files)
✓ codex-translator: emitted .codex/config.toml
$ ls -la
... AGENTS.md, CLAUDE.md, .claude/, .codex/, .samuel/ ...
$ samuel run init --prd .samuel/tasks/test-prd.md
✓ prd.toon created
$ samuel run start --iterations 1 --agent codex
... runs against Codex in OCI sandbox ...
Confirms: agnostic invariant holds (no CLAUDE.md until claude-translator installs), three plugin tiers all work (skill + WASM + OCI), starter pack installs cleanly, translator plugins do their job.
Acceptance criteria¶
- Migration script produces 76 valid plugin directories in
migration-output/(78 minus 2 dropped). - Each generated
samuel-plugin.tomlparses and validates. - All 76 repos pushed to
github.com/samuelpkg/samuel-*, taggedv1.0.0. - Each repo has a signed GitHub release with cosign signature.
-
samuel-registry/index.tomlhas 83 entries (76 ports + 7 Anthropic community). - Registry CI validates clean (schema OK, repos reachable, tags exist).
-
samuel-startermeta-plugin published;samuel install samuel-starterresolves the 12 dependencies and installs them. -
claude-translatorplugin installable; emits CLAUDE.md mirroring AGENTS.md. -
codex-translatorplugin installable; emits Codex-specific files. - End-to-end smoke test passes (commands above).
- No
.claude/files exist untilclaude-translatoris installed (agnostic invariant). -
samuel init --minimalskips starter pack entirely. -
samuel init --without create-rfd,security-auditinstalls 10 of the 12 starters.
Compatibility and migration¶
- For v1 users: v1's
samuel.yamlinstalledlist is meaningless in v2. The migration notice ([[../.samuel/tasks/0006-prd-polish-launch]]) explains: "v1's installed languages/frameworks/workflows are now plugins. Reinstall what you want viasamuel install <name>." - For v1 skill authors who customized: any v1 SKILL.md edits live at
.claude/skills/<name>/SKILL.md. v2 doesn't touch that path. Users can read their old customizations, port them to the v2 plugin (PR upstream or fork). - For Anthropic community plugins: registry uses
subpathreferences — content stays atgithub.com/anthropics/skills. We don't fork. If upstream changes, registry curators update thelatestfield (or leave atmainfor continuous tracking).
Risks¶
| Risk | Likelihood | Mitigation |
|---|---|---|
| GitHub API rate limits during bulk push | High | Batch in groups of 10 with sleeps. Resume from partial completion (script is idempotent). |
| Migration script generates malformed manifest for edge-case skills | Medium | Validate every generated manifest with samuel plugin validate (PRD 0003) before push. Manual review for the 5% of skills with non-standard frontmatter. |
| Anthropic upstream skill content changes after migration | Low | upstream = true flag in registry tells curators to defer to upstream. Re-running the migration regenerates subpath entries from current upstream state. |
| Per-plugin CI quota burns through GitHub Actions minutes | Low | Reusable workflow caches TinyGo install; releases trigger only on tag push (rare). Public repos have unlimited minutes. |
| TinyGo can't compile the translator plugins | Medium | Translator logic is simple (read AGENTS.md → write CLAUDE.md). TinyGo handles file IO via WASI. Fallback to Rust + wasm32-wasi if needed. |
| Bulk-creating 76 repos creates org clutter | Medium | Acceptable trade-off. Migration to github.com/samuel-plugins/* org is a future option if needed. |
| Smoke test catches integration bugs only post-migration | High | Run smoke test against a subset (5 plugins covering all three tiers) early — before pushing all 76. Iterate on bugs. |
| Cosign signing setup is per-plugin chore | Medium | The reusable workflow handles signing identically across all plugins. Plugin authors don't see the complexity. |
| Anthropic community plugins fail signature verification (they're not signed by us) | Certain | Registry's upstream = true flag tells the install path to skip signature requirement. --allow-unsigned not needed for these. |
Resolved decisions (2026-05-12)¶
-
samuel-starteropt-out granularity:--withoutaccepts comma-separated names AND negative wildcards.samuel init --without 'security-*'skips all matching starter plugins. -
commit-messageskill placement: confirmed in the starter pack (it was already in the list of 12). Samuel Way workflow used bysamuel run(per agent prompt about conventional commits). -
Migration script as a published utility: one-shot.
scripts/migrate-v1-skills.gois deleted after the 78-plugin migration. Future migrations have different shapes (per-plugin major bumps, not bulk porting). -
Anthropic community plugin update cadence:
latest = "main"— track upstream HEAD continuously. Cleaner operationally. Risk accepted: upstream changes could surface in user environments without curator review. Trade-off favors freshness; upstream changes are typically refinements, not breaking. -
Plugin README content: auto-generated from manifest for the 78 ports. Minimal but functional. Plugin authors can replace per-repo if they want richer docs.
-
Plugin docs page generation: yes —
docs/plugins/<name>.mdauto-generated at docs build time from the registry index + each plugin's README. Implementation lands in Milestone 6 polish.
Outcome¶
To be filled in post-v2.0 launch. Expected outcomes:
- All 78 v1 skills are accessible to v2 users via
samuel install <name>. - Average plugin install time < 5 seconds for skill tier, < 15 seconds for WASM tier (translator plugins).
- The
samuel-startermeta-plugin pattern is copied by other plugin authors (e.g.,samuel-rust-starter,samuel-fullstack-starter) within a year. - One or two of the 78 ports surface as misclassified — a skill that should have been kept built-in, or a plugin that should be in the starter pack but wasn't. Quick patches as v2.0.x releases.
Related artifacts¶
- [[0001|RFD 0001]] — plugin format (defines
kind = "skill",kind = "wasm",kind = "meta") - [[0002|RFD 0002]] — AGENTS.md primary (drives translator plugin design)
- [[0003|RFD 0003]] — manifest schema + Sigstore (defines what migration generates)
- [[0005|RFD 0005]] — plugin loader (the system that installs migrated plugins)
- [[0008|RFD 0008]] — gstack/gbrain drop (doesn't get migrated — these are dropped, not moved)
- [[../../wiki/sources/2026-05-12-v1-skill-content-survey]] — wiki source: full 78-skill triage
- [[../../wiki/synthesis/v2-skill-migration-plan]] — wiki synthesis: detailed migration approach
- PRD 0005 (Skill Migration) — implements all phases above