{
  "id": "2026-04-27-agent-capabilities-design-1a3e00df22",
  "scope": "redkey",
  "source_of_truth": "repo",
  "source_path": "docs/specs/2026-04-27-agent-capabilities-design.md",
  "source_kind": "markdown",
  "visibility": "internal",
  "renderer_id": "design_doc.dreamborn-forge.generated.v1",
  "design_system": "dreamborn-design-system:forge",
  "generated_at": "2026-05-09T13:00:55.676Z",
  "artifact_type": "design_doc",
  "schema_version": "design_doc.generated.v1",
  "title": "Agent Capabilities Design",
  "summary": "Agent Capabilities Design Date: 2026 04 27 Status: Draft Scope: How skills and plugins are defined, stored, and allocated to agents in the RedKey platform Problem Agents currently receive two things at runtime: a persona (inline text) and an MCP config (a file picked by naming convention). There is no structured concept of what an agent can do beyond its ide...",
  "format_source": "markdown",
  "sections": [
    {
      "title": "Agent Capabilities Design",
      "level": 1,
      "body": "**Date:** 2026-04-27  \n**Status:** Draft  \n**Scope:** How skills and plugins are defined, stored, and allocated to agents in the RedKey platform\n\n---"
    },
    {
      "title": "Problem",
      "level": 2,
      "body": "Agents currently receive two things at runtime: a persona (inline text) and an MCP config (a file picked by naming convention). There is no structured concept of what an agent *can do* beyond its identity text. Skills don't exist. Plugin assignment is implicit — `mcp-engine.json` exists because someone created it manually; there's no declaration in the agent definition that engine uses engine-tools.\n\nThis becomes a problem as the agent roster grows and capabilities multiply. Which agents can post to HCS? Which can browse the web? Which have access to git tooling? Today you have to read the MCP file and the persona string to find out. There's no single place to declare it.\n\n---"
    },
    {
      "title": "Goal",
      "level": 2,
      "body": "A structured capability model where:\n- Every discrete skill (how to do something) lives as a versioned markdown file\n- Every plugin (a tool that calls something external) has an explicit config\n- Each agent definition declares exactly which skills and plugins it gets\n- The runner loads the right content at startup with no manual MCP file management\n\n---"
    },
    {
      "title": "Taxonomy",
      "level": 2,
      "body": "Three distinct layers. Each has a different form, ownership model, and runtime role.\n\n| Layer | What it is | Form | Runtime role |\n|---|---|---|---|\n| **Skill** | Instructions for HOW to do something | Markdown file | Injected into system prompt after persona |\n| **Plugin** | Executable tool that calls something external | MCP server + config | Passed to Claude as MCP server |\n| **Agent** | Autonomous actor with identity and role | Definition JSON + persona | The entity that loads skills and calls plugins |\n\nAn agent loads skills to know *how* to do work. It calls plugins to *actually* do it. Skills are context. Plugins are capability.\n\n---"
    },
    {
      "title": "Directory Structure",
      "level": 2,
      "body": "```\ncapabilities/\n  skills/\n    <name>.md          # plain markdown, injected into system prompt\n  plugins/\n    <name>/\n      config.json      # MCP server config stub\n```\n\nPlugin `config.json` points to existing JS server files in `agents/shared/mcp/`. The JS does not move as part of this design — that is a separate concern.\n\nExample plugin config (`capabilities/plugins/hedera-tools/config.json`):\n\n```json\n{\n  \"server\": \"hedera-tools\",\n  \"command\": \"node\",\n  \"args\": [\"agents/shared/mcp/hedera-tools.js\"]\n}\n```\n\nThe `server` field becomes the key in the assembled `mcpServers` object. Runner produces: `{ \"mcpServers\": { \"hedera-tools\": { \"command\": \"node\", \"args\": [...] } } }`.\n\n---"
    },
    {
      "title": "Agent Definition Schema",
      "level": 2,
      "body": "Two new optional arrays added to each agent definition JSON:\n\n```json\n{\n  \"slug\": \"quinn\",\n  \"name\": \"Quinn\",\n  \"department\": \"dev\",\n  \"model\": \"claude-sonnet-4-6\",\n  \"schedule_seconds\": 120,\n  \"roles\": [\"developer\"],\n  \"skills\": [\"git-workflow\", \"spec-reading\"],\n  \"plugins\": [\"hedera-tools\"],\n  \"persona\": \"...\"\n}\n```\n\n- `skills` — names resolving to `capabilities/skills/<name>.md`\n- `plugins` — names resolving to `capabilities/plugins/<name>/config.json`\n- Both are optional. An agent with neither behaves exactly as today.\n- Declaration is explicit per agent. No role-based defaults, no bundles, no inheritance. If Quinn and Arlo share the same skills, they both list them. Abstraction comes later if repetition warrants it.\n\n---"
    },
    {
      "title": "Runtime Behavior",
      "level": 2,
      "body": "At agent startup the runner does, in order:\n\n1. Read `skills` and `plugins` arrays from `agent_definitions` in Supabase\n2. For each skill: read `capabilities/skills/<name>.md`, append to system prompt after persona under a `## Skills` section header\n3. For each plugin: read `capabilities/plugins/<name>/config.json`, assemble into a single `mcpServers` object, write to a temp file, pass to Claude\n\nSkills are additive — they extend what the agent knows, they don't replace identity. Plugin assembly replaces the current `mcp-{agent_id}.json` file convention.\n\n---"
    },
    {
      "title": "Source of Truth",
      "level": 2,
      "body": "| What | Source of truth | Runtime read |\n|---|---|---|\n| Skill/plugin names per agent | Definition JSON → synced to Supabase `agent_definitions` | Supabase (same as `roles`, `persona`) |\n| Skill content | `capabilities/skills/<name>.md` | File, at startup |\n| Plugin config | `capabilities/plugins/<name>/config.json` | File, at startup |\n\nSupabase holds arrays of names. File content is never synced to Supabase.\n\n---"
    },
    {
      "title": "What This Replaces",
      "level": 2,
      "body": "| Current | Replaced by |\n|---|---|\n| `agents/shared/mcp.json` (default) | Explicit `plugins` array in each definition |\n| `agents/shared/mcp-engine.json` | `\"plugins\": [\"engine-tools\"]` in `engine.json` |\n| `agents/shared/mcp-atlas.json` | `\"plugins\": [\"atlas-tools\"]` in `atlas.json` |\n| `_mcp_config_path()` naming convention in runner | Plugin assembly loop reading from `capabilities/` |\n\nOld `mcp-*.json` files are deleted after migration is complete.\n\n---"
    },
    {
      "title": "Out of Scope",
      "level": 2,
      "body": "- Moving MCP JS server files to `capabilities/plugins/` — file co-location is a separate cleanup\n- Role-based capability defaults or bundle grouping — premature until repetition patterns are clear\n- Capability discovery or marketplace indexing — future concern, not runtime allocation\n- Skill versioning or conflict resolution — not needed yet"
    }
  ],
  "html_path": "artifacts/2026-04-27-agent-capabilities-design-1a3e00df22.html",
  "json_path": "artifacts/2026-04-27-agent-capabilities-design-1a3e00df22.json"
}