--- type: decision tldr: Optional KB capabilities ship as file-based modules under `.agents/modules//`, installed into the KB on request, rather than as native Claude Code plugins. status: accepted decided_on: 2026-09-20 decided_by: Michał Kopeć affects: /wiki/index.md confidence: 0.9 quality: 0.8 last_updated: 2026-09-20 freshness_window_days: 365 retention: high --- # D-0001 — Optional KB capabilities ship as file-based modules, not native plugins **Status:** Accepted · **Decided:** 2026-09-20 · **Deciders:** Michał Kopeć ## Context The base KB ships fourteen `ckb-*` skills, all always loaded. Some capabilities are only useful to *some* knowledge bases — the first concrete case being a KB that documents software the user is building (see [[D-0002]] / [D-0002](/wiki/decisions/0002-software-module-design.md)). Adding those skills unconditionally would grow the always-loaded skill-description budget for every KB, including ones that will never need them. Three mechanisms were on the table for making a capability opt-in. The KB is deliberately agent-agnostic: `AGENTS.md` is the source of truth and `CLAUDE.md` is a symlink to it (git mode `120000`), as is `.claude/skills` → `.agents/skills`. That symlink arrangement is a confirmed preference, and it means anything written to `.agents/skills/` is visible to Claude Code for free. ## Decision Optional capabilities are packaged as **file-based modules** stored in `.agents/modules//` and installed into the KB on explicit request. A module may contribute skills (into `.agents/skills/`), directory scaffold, a routing block appended to `AGENTS.md`, and `.gitignore` rules. Installation is recorded in a root manifest listing the installed modules and their config; uninstalling reverses it. ## Rationale A module is a property of *the knowledge base*, not of the machine or the agent reading it. File-based modules travel with a clone, so a cloned KB stays self-describing, and they work for any agent that reads `AGENTS.md` — not only Claude Code. Shipping module content outside `.agents/skills/` until install keeps the always-loaded skill budget flat for KBs that don't opt in. ## Consequences - A `ckb-module`-style install/uninstall path is needed. - `ckb-init` should offer modules at bootstrap; `ckb-upgrade` must not delete module-installed skills it doesn't recognise upstream, and must also upgrade `.agents/modules/`. - `ckb-lint` gains validation of the module manifest. - Module skills are authored so they could *also* be published as a native Claude Code plugin later without a rewrite — this decision doesn't foreclose that, it just declines to make it the primary mechanism. - Because `.claude/skills` is a symlink, an installer writes `.agents/skills/` only; no duplicate copy to keep in sync. ## Alternatives considered - **Always-shipped skills that self-gate on a flag** — no install step and trivially upgradeable, but every skill description stays in context for every KB regardless of relevance. Rejected: that budget degrades quietly. - **Native Claude Code plugin** (`.claude-plugin/plugin.json` + marketplace) — real enable/disable and no file copying, but serves only Claude Code, breaking the dual-headed `AGENTS.md`/`CLAUDE.md` contract, and installs per-machine rather than per-KB. Rejected as the primary mechanism, not ruled out as an additional distribution channel. ## Sources Chat conversation, 2026-09-20 — design evaluation of a source-code/software KB mode. See `workload/2026-09-20_summary.md`.