diff --git a/docs/21-agent-evolution-and-skill-management.md b/docs/21-agent-evolution-and-skill-management.md
index bf0bc5d0..e8aa704b 100644
--- a/docs/21-agent-evolution-and-skill-management.md
+++ b/docs/21-agent-evolution-and-skill-management.md
@@ -8,6 +8,56 @@ Three subsystems enable agents to evolve their behavior and capture reusable wor
| Skill Learning | Agent learns to create skills from experience | System prompt guidance + nudges + consent | `skill_evolve` |
| Skill Management | Create, patch, delete, grant skills | `skill_manage` tool + HTTP/WS API | (always available when skill_evolve=true) |
+```mermaid
+graph TB
+ subgraph ADMIN["Admin Configuration"]
+ SE["self_evolve = true"]
+ SKE["skill_evolve = true"]
+ end
+
+ subgraph EVOLUTION["Agent Evolution"]
+ SOUL["SOUL.md
(tone/voice)"]
+ SKILL["Skill Creation
(reusable workflows)"]
+ end
+
+ subgraph PROMPT["System Prompt Injection"]
+ SEP["Self-Evolve Section
CAN / MUST NOT"]
+ SKP["Skill Creation Section
SHOULD / SHOULD NOT"]
+ end
+
+ subgraph LOOP["Agent Loop"]
+ N70["70% budget nudge"]
+ N90["90% budget nudge"]
+ PS["Postscript suggestion"]
+ end
+
+ subgraph TOOLS["Tools"]
+ WF["write_file → SOUL.md"]
+ SM["skill_manage
(create/patch/delete)"]
+ end
+
+ subgraph STORE["Storage"]
+ FS["Filesystem
(skills-store/)"]
+ DB["PostgreSQL
(skills table)"]
+ GRANTS["Grants
(agent/user)"]
+ end
+
+ SE --> SEP
+ SKE --> SKP
+ SKE --> N70 & N90 & PS
+ SEP --> WF
+ SKP --> SM
+ PS -.->|user consent| SM
+ WF --> SOUL
+ SM --> FS & DB
+ DB --> GRANTS
+
+ style ADMIN fill:#e8f5e9,stroke:#2e7d32
+ style LOOP fill:#fff3e0,stroke:#ef6c00
+ style TOOLS fill:#e3f2fd,stroke:#1565c0
+ style STORE fill:#f3e5f5,stroke:#7b1fa2
+```
+
---
## 1. Self-Evolution (SOUL.md)
@@ -96,36 +146,30 @@ Open agents always get `skillEvolve=false` regardless of DB setting.
### 2.3 Lifecycle Flow
-```
-Admin enables skill_evolve in agent config
- │
- ▼
-System prompt includes "### Skill Creation" guidance
- │
- ▼
-Agent processes user request (think→act→observe loop)
- │
- ├─ At 70% iteration budget ─► ephemeral nudge (soft suggestion)
- ├─ At 90% iteration budget ─► ephemeral nudge (moderate urgency)
- │
- ▼
-Agent completes task (totalToolCalls >= skill_nudge_interval?)
- │
- ├─ No ─► Normal response, no postscript
- │
- ├─ Yes ─► Postscript appended:
- │ "Want me to save the process as a reusable skill?"
- │ User replies "save as skill" or "skip"
- │ │
- │ ├─ "skip" ─► No action
- │ │
- │ └─ "save as skill" ─► Agent calls skill_manage(action="create")
- │ │
- │ ▼
- │ Skill created, auto-granted,
- │ available on next turn
- │
- └─ skill_manage filtered from LLM when skill_evolve=false
+```mermaid
+flowchart TD
+ A["Admin enables
skill_evolve"] --> B["System prompt includes
Skill Creation guidance"]
+ B --> C["Agent processes request
(think→act→observe)"]
+ C --> D{"Iteration budget
milestone?"}
+ D -->|"≥ 70%"| E["Ephemeral nudge
(soft suggestion)"]
+ D -->|"≥ 90%"| F["Ephemeral nudge
(moderate urgency)"]
+ D -->|"< 70%"| G["Continue processing"]
+ E --> G
+ F --> G
+ G --> H["Agent completes task"]
+ H --> I{"totalToolCalls ≥
skill_nudge_interval?"}
+ I -->|No| J["Normal response"]
+ I -->|Yes| K["Postscript appended:
Save as skill? or skip?"]
+ K --> L{"User reply"}
+ L -->|"skip"| M["No action"]
+ L -->|"save as skill"| N["Agent calls
skill_manage(create)"]
+ N --> O["Skill created +
auto-granted"]
+ O --> P["Available on
next turn"]
+
+ style A fill:#e8f5e9,stroke:#2e7d32
+ style K fill:#fff3e0,stroke:#ef6c00
+ style N fill:#e3f2fd,stroke:#1565c0
+ style O fill:#f3e5f5,stroke:#7b1fa2
```
### 2.4 System Prompt Guidance
@@ -242,52 +286,43 @@ Admin management via HTTP API + WebSocket RPC. Grants system controls per-agent
| `find` | string | patch | Exact text to find in current SKILL.md |
| `replace` | string | patch | Replacement text |
-**Create flow:**
+**Operations flow:**
-```
-content string
- │
- ├─ Size check (max 100KB)
- ├─ Security scan (GuardSkillContent)
- ├─ Parse frontmatter (name, description, slug)
- ├─ Slug validation (lowercase alphanumeric + hyphens)
- ├─ System skill conflict check
- ├─ Version + directory creation
- ├─ Write SKILL.md to skills-store/{slug}/{version}/
- ├─ SHA-256 hash
- ├─ DB insert (CreateSkillManaged with advisory lock)
- ├─ Auto-grant to calling agent
- ├─ Cache invalidation (BumpVersion)
- └─ Dependency scan (best-effort, warn only)
-```
+```mermaid
+flowchart LR
+ subgraph CREATE["action = create"]
+ direction TB
+ C1["Content string"] --> C2["Size ≤ 100KB?"]
+ C2 --> C3["Security scan"]
+ C3 --> C4["Parse frontmatter"]
+ C4 --> C5["Slug validation"]
+ C5 --> C6["System skill
conflict check"]
+ C6 --> C7["Write SKILL.md
to versioned dir"]
+ C7 --> C8["DB insert
(advisory lock)"]
+ C8 --> C9["Auto-grant +
dep scan"]
+ end
-**Patch flow:**
+ subgraph PATCH["action = patch"]
+ direction TB
+ P1["slug + find/replace"] --> P2["Exists?
System skill?"]
+ P2 --> P3["Ownership check"]
+ P3 --> P4["Read current +
apply patch"]
+ P4 --> P5["Security scan
patched content"]
+ P5 --> P6["New version
(advisory lock)"]
+ P6 --> P7["Copy companions +
DB update"]
+ end
-```
-slug + find + replace
- │
- ├─ Skill exists? System skill?
- ├─ Ownership check (owner only)
- ├─ Read current SKILL.md
- ├─ Apply find/replace
- ├─ Security scan on patched content
- ├─ Get next version (with advisory lock)
- ├─ Write new SKILL.md
- ├─ Copy companion files (scripts, assets)
- ├─ DB update (version, file_path, file_hash)
- └─ Cache invalidation
-```
+ subgraph DELETE["action = delete"]
+ direction TB
+ D1["slug"] --> D2["Exists?
System skill?"]
+ D2 --> D3["Ownership check"]
+ D3 --> D4["Move to .trash/"]
+ D4 --> D5["DB archive +
cascade grants"]
+ end
-**Delete flow:**
-
-```
-slug
- │
- ├─ Skill exists? System skill?
- ├─ Ownership check (owner only)
- ├─ Soft-delete disk: mv skills-store/{slug} → .trash/{slug}.{timestamp}
- ├─ DB archive: status='archived', cascade delete grants
- └─ Cache invalidation
+ style CREATE fill:#e8f5e9,stroke:#2e7d32
+ style PATCH fill:#fff3e0,stroke:#ef6c00
+ style DELETE fill:#ffebee,stroke:#c62828
```
### 3.3 publish_skill Tool
@@ -333,23 +368,34 @@ All endpoints require authentication (`authMiddleware`). Mutation endpoints requ
### 3.6 Grants & Visibility
+```mermaid
+stateDiagram-v2
+ direction LR
+
+ [*] --> private : Skill created
+ private --> internal : GrantToAgent / GrantToUser
+ internal --> private : Last grant revoked
+ internal --> public : Admin promotes
+
+ state private {
+ [*] : Owner only
+ }
+ state internal {
+ [*] : Granted agents/users
+ }
+ state public {
+ [*] : All agents
+ }
```
-Skill created with visibility = "private"
- │
- ▼
-Auto-grant to creating agent
- → visibility auto-promoted to "internal"
- │
- ▼
-ListAccessible query includes:
- - is_system = true (all system skills)
- - visibility = 'public' (anyone)
- - visibility = 'private' (owner only)
- - visibility = 'internal' (agents/users with grants)
- │
- ▼
-Revoke last grant → auto-demotes "internal" → "private"
-```
+
+**Access resolution** (`ListAccessible` query):
+
+| Visibility | Who can access |
+|------------|---------------|
+| `public` | All agents |
+| `internal` | Agents/users with explicit grants |
+| `private` | Owner only |
+| `is_system=true` | All agents (always) |
Grant/revoke operations require **ownership or admin role**.
@@ -357,6 +403,26 @@ Grant/revoke operations require **ownership or admin role**.
## 4. Security Model
+```mermaid
+flowchart TB
+ REQ["Skill mutation request"] --> L1{"Layer 1:
Content Guard"}
+ L1 -->|"violation"| REJECT["Rejected"]
+ L1 -->|"safe"| L2{"Layer 2:
Ownership Check"}
+ L2 -->|"not owner
& not admin"| REJECT
+ L2 -->|"owner or admin"| L3{"Layer 3:
System Skill?"}
+ L3 -->|"is_system=true"| REJECT
+ L3 -->|"custom skill"| L4{"Layer 4:
Filesystem Safety"}
+ L4 -->|"symlink / traversal /
size exceeded"| REJECT
+ L4 -->|"safe"| OK["Mutation applied"]
+
+ style REJECT fill:#ffebee,stroke:#c62828
+ style OK fill:#e8f5e9,stroke:#2e7d32
+ style L1 fill:#fff3e0,stroke:#ef6c00
+ style L2 fill:#e3f2fd,stroke:#1565c0
+ style L3 fill:#f3e5f5,stroke:#7b1fa2
+ style L4 fill:#fce4ec,stroke:#ad1457
+```
+
### 4.1 Content Guard (`guard.go`)
Line-by-line regex scan of SKILL.md content **before** any disk write. Hard-reject on ANY violation. 25 rules in 6 categories: