ADR-0035: Decouple skill and agent installation from project initialization
Status: accepted | Date: 2026-03-17
Tags:
skills-agents
References: RFC-0002, ADR-0033, ADR-0028
Context
govctl init currently bundles three concerns into one command: governance directory scaffolding (gov/), JSON Schema deployment, and agent asset installation (skills + agents to .claude/). ADR-0033 introduced plugin distribution, giving users a second path to receive skills and agents — globally, via the Claude Code plugin system.
Problem Statement
- Redundant local copies for plugin users. Users who install govctl as a Claude Code plugin receive skills and agents globally.
govctl initalso writes them locally, creating two copies with unclear authority. - Missing schemas for old projects. Projects initialized with earlier govctl versions lack
gov/schema/*.jsonfiles. The#:schemarelative-path comments in TOML artifacts resolve to nonexistent files, breaking IDE validation. Neithergovctl syncnorgovctl migratefills this gap. - Unclear
syncnaming.govctl synconly syncs agent assets (skills + agents), but the name implies general synchronization.
Constraints
- RFC-0002:C-GLOBAL-COMMANDS specifies
initwith “optionally creates.claude/commands/” — the skill dump was always optional. - RFC-0002:C-GLOBAL-COMMANDS requires new global commands to be added via RFC amendment and meet at least one criterion (multi-resource, project-level init/cleanup, or meta-information).
govctl syncis not specified in RFC-0002 — it exists only as an implementation convenience.
Decision
We will separate the three concerns as follows:
-
govctl initcreates governance structure (gov/directories,config.toml, JSON Schemas). It no longer installs skills or agents. After completion, it prints a hint aboutgovctl init-skillsand plugin installation. -
govctl init-skills(replacesgovctl sync) explicitly installs skills and agents into the configuredagent_dir. This is the opt-in command for users who do not use the plugin. Supports-fto overwrite existing files. -
govctl migrateensures all bundled JSON Schema files exist ingov/schema/, always overwriting with the latest version. This fills the gap for projects initialized with older govctl versions.
Implementation Notes
initremoves the skill/agent writing loop and the hardcoded.claudepath.init-skillsreuses the existingsync_commands()implementation unchanged.migrateadds a schema-sync step that runs unconditionally (not gated by schema version), writing allARTIFACT_SCHEMA_TEMPLATESentries toconfig.schema_dir().- RFC-0002:C-GLOBAL-COMMANDS is amended to add
init-skillsand update theinitandmigratedescriptions.
Consequences
Positive
- Plugin users no longer get redundant local skill/agent copies from
init - Old projects get working
#:schemacomments after runninggovctl migrate - Command names are self-documenting:
init= governance,init-skills= agent assets - The hardcoded
.claudepath ininitis eliminated;init-skillsuses the configuredagent_dir
Negative
- Users who had
govctl initin onboarding docs will find.claude/empty after upgrading (mitigation:initprints a hint, and the changelog documents the change) - Two commands instead of one for full setup (mitigation: plugin users need zero commands for agent assets; CLI-only users run
inittheninit-skills)
Neutral
govctl syncis removed as a command name;init-skillsreplaces it- Schema files are now overwritten on every
migraterun, even if unchanged — this is safe since they are generated artifacts
Alternatives Considered
Keep init bundled: init continues to dump skills/agents alongside governance structure (rejected)
- Cons: Redundant for plugin users, Hardcoded .claude path ignores agent_dir config
- Rejected because: Plugin distribution per ADR-0033 makes unconditional local dumping obsolete
Add –skills flag to init instead of separate command: govctl init –skills dumps agent assets (rejected)
- Cons: Discovery problem: users must know the flag exists, Couples governance init with agent concerns
- Rejected because: Separate command is more discoverable and aligns with single-responsibility