# adr-plugin-packaging ## ADDED Requirements ### Requirement: Plugin naming and skill naming conventions The plugin SHALL be named `os-adr` (kebab-case, `os-` prefix) and its skills SHALL use verb-first kebab-case names invoked as `/os-adr:` (`create`, `init`, `migrate`, `find`), with no `commands/` dispatcher directory — matching the cc-os plugin/skill naming convention. #### Scenario: Skills register under verb-first names - **WHEN** the plugin is installed and `claude plugin details os-adr@local-plugins` is run - **THEN** the listed skills are `create`, `init`, `migrate`, and `find`, and no `commands/` directory exists in the plugin ### Requirement: Source of truth in cc-os with symlinked install The plugin source SHALL live git-tracked at `cc-os/plugins/os-adr/` and be installed via a symlink `~/.claude/plugins/os-adr` pointing at it, matching the `os-vault`/`os-doc-hygiene`/ `os-orchestration` pattern. #### Scenario: Symlinked install - **WHEN** installation is complete - **THEN** `~/.claude/plugins/os-adr` is a symlink resolving to the git-tracked plugin directory ### Requirement: Full three-place marketplace registration Installation SHALL update all three registration surfaces — the plugin directory/symlink, the `local-plugins` marketplace manifest (`~/.claude/plugins/.claude-plugin/marketplace.json`), and `settings.json` `enabledPlugins` — then refresh plugin-manager state via `claude plugin marketplace update` and `claude plugin install`, and verify skill registration with `claude plugin list` and `claude plugin details`. #### Scenario: Skills resolve after install - **WHEN** the registration procedure completes - **THEN** `claude plugin list` shows `os-adr@local-plugins` enabled and its skills are invocable as slash commands in a fresh session ### Requirement: Hooks wired through plugin hooks.json Plugin hooks SHALL be declared in `hooks/hooks.json` using `${CLAUDE_PLUGIN_ROOT}`-relative commands (the `os-doc-hygiene` pattern), not by absolute paths in `settings.json`, so hook registration cannot silently outlive or diverge from plugin registration. #### Scenario: Hook path is plugin-relative - **WHEN** the plugin's hook configuration is inspected - **THEN** the SessionStart command references `${CLAUDE_PLUGIN_ROOT}` and no os-adr hook entry exists in `settings.json` ### Requirement: OO core with tested deterministic behavior The plugin's core logic SHALL be implemented as an object-oriented Ruby library (small single-responsibility classes, dependency-injected paths/IO, no globals) exposed through thin CLI entry points, with a thin Python script only for the SessionStart hook. All deterministic behaviors (ID assignment, index regeneration, shape detection, existence check, retrieval layers 1–2) SHALL have automated tests runnable without any LLM, including golden-example fixtures. #### Scenario: Deterministic tests run model-free - **WHEN** the plugin's test suite runs on a machine with no model access - **THEN** all tests for ID assignment, index regeneration, detection, existence check, and frontmatter retrieval pass #### Scenario: Skills delegate to CLI entry points - **WHEN** a skill performs a mechanical operation (numbering, indexing, detection, filtering) - **THEN** it does so by invoking a `bin/` CLI rather than re-implementing the logic in prompt instructions