# Skills and protocols

The catalog behind the agent's methodologies: reusable **skills** (how to approach
a kind of task) and **protocols** (a strict, pre-agreed order of actions). One
registry, one document format, one place in settings.

## Skills vs protocols vs manuals

| | manual | skill | protocol |
|---|---|---|---|
| answers | "how does this tool work" | "how do I approach this" | "what exactly to do, in what order" |
| written by | developers | the agent, freely | the agent proposes, the user accepts |
| strictness | reference | advice, adapt as needed | commitment; deviation is an error to report |
| storage | `manuals/*.md` in the repo | catalog row | catalog row |

A skill is injected as instructions and nothing more — no run, no report. A
protocol has an explicit start, mandatory checks, and an explicit finish with a
report (the run machinery builds on the todo plan; see
[todo-store.md](todo-store.md)).

## Document format

Markdown with a YAML front matter block:

```markdown
---
kind: protocol
name: Корректное выключение инфраструктуры
description: Останавливает сервисы в порядке зависимостей и проверяет диск.
area: infrastructure
tags: [power, shutdown]
triggers:
  - "пользователь просит выключить сервер"
steps:
  - "Остановить приложения"
  - "Остановить базы данных"
  - "Синхронизировать и отмонтировать диски"
preconditions:
  - "Все пользователи предупреждены"
post_checks:
  - "Прикладных юнитов не осталось"
on_deviation: "Не продолжать; вернуться к предыдущему шагу и доложить."
on_blocked: "Остановить процесс и доложить, что именно не дало завершить."
on_already_done: "Проверить статус; если результат уже есть — отметить шаг."
---

Контекст: порядок зависимостей, известные ловушки, что занимает время.
```

### Fields

| Field | skill | protocol |
|---|---|---|
| `kind` | required | required |
| `name` | required, unique per owner | required, unique per owner |
| `description` | recommended | recommended |
| `triggers` | optional list — when to use it | optional list — when the protocol applies |
| `tags` | optional | optional |
| `area` | `home` \| `infrastructure` \| `workflows` \| `general` (default) | same |
| `steps` | — | **required** |
| `preconditions` | — | optional list |
| `post_checks` | — | **required** — how each step's result is verified |
| `on_deviation` | — | **required** — the run drifted from the plan |
| `on_blocked` | — | **required** — the protocol cannot be completed |
| `on_already_done` | — | **required** — a step's result already exists |
| body | **required** — the instructions | the context around the steps |

Validation is strict on purpose: a protocol without its three escape hatches
cannot be executed honestly when reality differs from the plan, so the store
refuses it with a message naming the missing keys.

Unknown front matter keys are preserved in the JSONB copy, so extra metadata
(`owner_team`, `reviewed_by`) survives a round trip through the editor.

## Storage

Two tables (PostgreSQL, lazy DDL on first use):

```sql
CREATE TABLE skills (
    id TEXT PRIMARY KEY, kind TEXT, name TEXT, description TEXT,
    triggers TEXT[], tags TEXT[], area TEXT,
    visibility TEXT, owner_id TEXT,      -- 'personal' | 'shared'
    content TEXT, frontmatter JSONB,
    version INTEGER, content_hash TEXT,
    created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, updated_by TEXT
);
CREATE TABLE skill_versions (
    id BIGSERIAL PRIMARY KEY, skill_id TEXT REFERENCES skills(id) ON DELETE CASCADE,
    version INTEGER, content TEXT, frontmatter JSONB, content_hash TEXT,
    edited_by TEXT, reason TEXT, created_at TIMESTAMPTZ,
    UNIQUE (skill_id, version)
);
```

- **Ownership**: personal rows have `owner_id = <user>`; shared rows have
  `owner_id = ''` and are writable only by an admin. An admin creates both; a
  regular user creates personal entries only.
- **Uniqueness**: `(owner_id, kind, name)` — the same name may exist once
  personally and once shared without colliding.
- **Versioning**: every create and update appends to `skill_versions`; `version`
  on the row is the latest. History keeps `edited_by` and `reason`.
- **`content_hash`** is the SHA-256 of the document. It is the only
  hive-synchronization hook committed so far; the sync service itself (instance
  registry in the hive) is future work.

## Search

`SkillStore.list(user_id, kind?, query?, tag?, area?, limit)` returns what the
user may see (own + shared), personal first, then most recently updated.
`query` matches name, description, triggers and tags. The agent's `skills` tool
uses the same query; the settings tab uses the HTTP API.

## REST API

All endpoints require a logged-in user.

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/skills?kind=&q=&tag=&area=&limit=` | catalog for the current user |
| `GET` | `/skills/{id}` | one entry with the full document |
| `POST` | `/skills` | create; body `{content, visibility?, reason?}` |
| `PUT` | `/skills/{id}` | edit; body `{content, reason?, visibility?}` |
| `DELETE` | `/skills/{id}` | remove (history cascades) |
| `GET` | `/skills/{id}/versions?limit=` | edit history, newest first |

`visibility: shared` on create or change requires `role == "admin"`.

## Agent tool

`skills` — `search` and `load`:

```json
{"op": "search", "query": "выключение", "area": "infrastructure"}
{"op": "load", "id": "3f2a9c1d8e4b7a60"}
```

`load` renders a compact document: for a protocol, preconditions, numbered steps,
post-checks and the three escape hatches; for a skill, the instructions. The
tool is available to `assistant`, `developer`, `server_admin` and `discuss`.

## Settings tab

Settings → **Скилы и протоколы**: the catalog list with a search box and kind/
area filters, a document editor that shows the server's validation error
verbatim, create from a skill or protocol template, delete, and the edit history.
An admin can also move an entry between personal and shared; for everyone else a
shared entry opens read-only.

## Not implemented yet

- Agent-created skills from chat and protocol **proposals** with
  "Добавить"/"Отклонить" buttons (planned next step).
- `protocol_start` / `protocol_finish` / `protocol_cancel` / `protocol_fail` and
  run logging.
- Hive synchronization of shared entries (schema is ready: `content_hash`,
  `version`).
