---
name: builtin-agent-skill
description: >
  Adding a built-in Agent Skill (an attack technique like ssrf, xxe, rce) that
  ships hardcoded in RedAmon: classified by the Intent Router, injected into the
  agent prompt, toggled per project, badged in the chat drawer. Nine layers
  across agentic and webapp, two of which fail with no error.
  Trigger: adding or editing a built-in attack skill; a new
  agentic/prompts/<skill_id>_prompts.py; editing agentic/prompts/classification.py,
  agentic/prompts/__init__.py _inject_builtin_skill_workflow, KNOWN_ATTACK_PATHS
  in agentic/state.py, or the webapp AttackSkillsSection / AIAssistantDrawer.
license: MIT
metadata:
  author: redamon
  version: "1.0.0"
  scope: [agentic, webapp]
  auto_invoke:
    - "Adding a built-in attack skill to the agent"
    - "Editing agent skill classification, phase injection, or the attack-skill UI"
---

## When to Use

- Adding a first-class attack technique the agent classifies and follows a workflow for.

For a user-uploadable workflow, use `add-community-skill`
instead. For a *tool* the agent calls, use `agentic-tool-integration`.
For per-skill tunable defaults, use `project-settings-cascade`.

---

## Critical Rules

- **ALWAYS add the skill id to `KNOWN_ATTACK_PATHS`** in
  [agentic/state.py](../../agentic/state.py). It is the Pydantic validator's
  allowlist; miss it and the classifier's output is **rejected at runtime** even
  though every other layer is wired.
- **NEVER skip layers 8 and 9** (the chat-drawer layers). They live in webapp and
  produce **no error** when forgotten: the skill classifies and badges, but the
  drawer tooltip and one-click example prompts are silently missing. Layer 8 =
  `BUILT_IN_SKILLS` in [attack-skills/available/route.ts](../../webapp/src/app/api/users/[id]/attack-skills/available/route.ts);
  Layer 9 = a `SESubGroup` in [suggestionData.ts](../../webapp/src/app/graph/components/AIAssistantDrawer/suggestionData.ts).
- **NEVER let classification keywords overlap an existing skill.** Every enabled
  built-in competes for the same user message; overlapping keywords (e.g. saying
  "SQL" in an SSRF section) make both skills mis-route. Disambiguate in the
  "Key distinction" line of the section in [classification.py](../../agentic/prompts/classification.py).
- **ALWAYS gate the workflow on the required tool** inside
  `_inject_builtin_skill_workflow()` ([agentic/prompts/__init__.py:509](../../agentic/prompts/__init__.py#L509)):
  `and "<tool>" in allowed_tools`. Without the guard the agent gets instructions
  for a tool `TOOL_PHASE_MAP` blocks in that phase.
- **NEVER assume existing projects inherit the new skill.** `builtIn` is a strict
  has-key check; existing projects need a jsonb update to `attackSkillConfig`.
- **Pick the snake_case id once and use that exact literal in all 9 layers.**
  `grep -rn "<skill_id>" webapp/src agentic` must show it everywhere before you
  rebuild (an existing id like `cve_exploit` spans ~38 files).

---

## The nine layers (all required end to end)

| # | Layer | File |
| --- | --- | --- |
| 1 | Workflow prompt | `agentic/prompts/<skill_id>_prompts.py` |
| 2 | Package re-export + `__all__` | [agentic/prompts/__init__.py](../../agentic/prompts/__init__.py) |
| 3 | Phase injection branch | `_inject_builtin_skill_workflow()` (same file) |
| 4 | Classification + validator | [classification.py](../../agentic/prompts/classification.py) `_BUILTIN_SKILL_MAP` **and** `KNOWN_ATTACK_PATHS` in [state.py](../../agentic/state.py) |
| 5 | Settings default | `ATTACK_SKILL_CONFIG.builtIn` in [agentic/project_settings.py](../../agentic/project_settings.py) |
| 6 | Prisma default | `attackSkillConfig` JSON in [schema.prisma](../../webapp/prisma/schema.prisma) |
| 7 | UI toggle + badge | [AttackSkillsSection.tsx](../../webapp/src/components/projects/ProjectForm/sections/AttackSkillsSection.tsx) + [phaseConfig.ts](../../webapp/src/app/graph/components/AIAssistantDrawer/phaseConfig.ts) |
| 8 | Drawer tooltip | [attack-skills/available/route.ts](../../webapp/src/app/api/users/[id]/attack-skills/available/route.ts) `BUILT_IN_SKILLS` |
| 9 | Drawer example prompts | [suggestionData.ts](../../webapp/src/app/graph/components/AIAssistantDrawer/suggestionData.ts) |

## Commands

```bash
docker compose build agent && docker compose up -d agent   # agentic/ is baked
docker compose exec webapp npx prisma db push              # NEVER prisma migrate
# verify the id is wired everywhere before rebuild:
grep -rn "<skill_id>" webapp/src agentic
```

## Resources

- [docs/readmes/coding_agent_prompts/PROMPT.ADD_BUILTIN_AGENT_SKILL.md](../../docs/readmes/coding_agent_prompts/PROMPT.ADD_BUILTIN_AGENT_SKILL.md) - full per-layer walkthrough, tunable-design patterns, failure triage
- Related skills: `agentic-tool-integration`, `project-settings-cascade`, `add-community-skill`
