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_PATHSin 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_SKILLSin attack-skills/available/route.ts; Layer 9 = aSESubGroupin 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.
- ALWAYS gate the workflow on the required tool inside
_inject_builtin_skill_workflow()(agentic/prompts/init.py:509):and "<tool>" in allowed_tools. Without the guard the agent gets instructions for a toolTOOL_PHASE_MAPblocks in that phase. - NEVER assume existing projects inherit the new skill.
builtInis a strict has-key check; existing projects need a jsonb update toattackSkillConfig. - ALWAYS add a registry entry for a per-skill tunable that became a
Projectcolumn in recon_settings/registry.yaml. A test walkingPrisma.ProjectScalarFieldEnumfails until every column has one. Draft it withpython3 tooling/scripts/extract_recon_registry.py, edit it, thenpython3 recon_settings/build.py. An attack-skill tunable is ordinarymcp: settabletuning now, bounded by its registry entry and gated at scan start byroeForbiddenCategories,roeForbiddenToolsandroeAllowDosrather than by being unreachable. Give ittraffic: activeso it joins the queued-job fingerprint, androe_capped: trueif its unit isrps. - Pick the snake_case id once and use that exact literal in all 9 layers.
grep -rn "<skill_id>" webapp/src agenticmust show it everywhere before you rebuild (an existing id likecve_exploitspans ~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 |
| 3 | Phase injection branch | _inject_builtin_skill_workflow() (same file) |
| 4 | Classification + validator | classification.py _BUILTIN_SKILL_MAP and KNOWN_ATTACK_PATHS in state.py |
| 5 | Settings default | ATTACK_SKILL_CONFIG.builtIn in agentic/project_settings.py |
| 6 | Prisma default | attackSkillConfig JSON in schema.prisma |
| 7 | UI toggle + badge | AttackSkillsSection.tsx + phaseConfig.ts |
| 8 | Drawer tooltip | attack-skills/available/route.ts BUILT_IN_SKILLS |
| 9 | Drawer example prompts | suggestionData.ts |
Commands
bashdocker 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 - full per-layer walkthrough, tunable-design patterns, failure triage
- Related skills:
agentic-tool-integration,project-settings-cascade,add-community-skill

