diff --git a/.tasks/2026-08-24-01059-mappa-knowledge.md b/.tasks/2026-08-24-01059-mappa-knowledge.md index 4234ac1..58d4c4b 100644 --- a/.tasks/2026-08-24-01059-mappa-knowledge.md +++ b/.tasks/2026-08-24-01059-mappa-knowledge.md @@ -17,4 +17,14 @@ Relational/структурные вопросы (связи, backlinks, сир ## Completed steps +- [x] skills/mappa-knowledge/SKILL.md v1.0.0 — слияние using-wiki v2.2.0 + using-wiki-graph v1.1.0 в один цикл-скил (ingest/query/lint + граф-слой для реляционных/структурных вопросов) +- [x] Старые skills/using-wiki/ + skills/using-wiki-graph/ удалены (поглощены; имена — триггер-синонимы в description) +- [x] lint clean (67 skills, 0 violations) +- [x] build.sh → dist/mappa-knowledge.skill; install.sh → dual targets; старые удалены из живых диров +- [x] GREEN micro-test: свежий pi -p на реляционном вопросе (связь таска↔спека) → активация mappa-knowledge, граф-слой (graph_path→no-path, backlinks), корректная семантика рёбер +- [x] Писано нейтрально (summaries/#1026 не упоминается); реф-конвенция полными именами (#1028, уже была в исходниках) + ## Notes + +- RED-базис: триггер-поверхность унаследована из using-wiki/using-wiki-graph (прошли ревью); дельта = слияние + цикл-фрейминг + guarded failure-mode графа. Полный behavioral smoke — за #1065. +- Побочная lint-находка GREEN-теста: рефы в прозе (не [[викилинки]]) рёбер не дают → спека может быть сиротой, «таска↔спека» в графе теряется. Это известная семантика решения 4 (рёбра только из [[refs]]), не баг скила — отмечено как наблюдение, кандидат в follow-up, если понадобится проставлять [[викилинки]] при создании тасок-промоушена. diff --git a/skills/mappa-knowledge/SKILL.md b/skills/mappa-knowledge/SKILL.md new file mode 100644 index 0000000..1ec11e1 --- /dev/null +++ b/skills/mappa-knowledge/SKILL.md @@ -0,0 +1,261 @@ +--- +name: mappa-knowledge +author: ours +version: 1.0.0 +description: > + Цикл работы со знаниями проекта в Mappa (Karpathy LLM Wiki, канал = + mappa-сущности): ingest → query → lint + граф-слой для + реляционных/структурных вопросов. Поглощает using-wiki + using-wiki-graph + (старые имена — триггер-синонимы). Триггеры: «заингесть», «обнови вики», + «запроси вики», «проверь вики», «use project wiki», «query the wiki», + «что связывает X и Y», «как связаны», «путь между X и Y», «what connects + X and Y», «что ссылается на X», «backlinks of X», «сироты», «битые ссылки», + «orphan pages». Wiki = сущности type=wiki (чтение — карв-аут лиза; запись — + под лизом проекта, решение 19). Реляционные вопросы — через graph_* (BFS на + стороне сервиса), guarded failure-mode: одна страница и стоп, без + многохоповых цепочек чтением. Skip для одно-страничных контентных вопросов. +--- + +# mappa-knowledge + +Единый цикл работы со знаниями проекта в **Mappa**: три операции (ingest / +query / lint) + **граф-слой** для реляционных и структурных вопросов. Скилл = +цикл, не тул: знание **компилируется один раз и держится актуальным** +(ingest), к нему обращаются (query), его проверяют (lint), а связи между +сущностями читают через граф (graph_*). + +Канал — Mappa (`mcp__mappa__*`), НЕ файлы. Страница — сущность `type=wiki` +(`wiki:N`); чтение — карв-аут лиза, запись — под лизом проекта (решение 19). +Файлового `.wiki/` больше нет; `setup-wiki` умер (нечего настраивать). + +## Когда использовать + +- Заингестить документ/источник в вики («заингесть X», «обнови вики»). +- Ответить из вики / проверить вики («запроси вики», «проверь вики», lint). +- Реляционный/структурный вопрос («что связывает X и Y», «backlinks», «сироты») — граф-слой. +- Модифицировать любую страницу — форматы ниже обязательны; конвенции проекта + живут в `AGENTS`-сущности (legacy — `CLAUDE`-указатель). + +**НЕ для:** разовых вопросов по коду (обычное чтение файлов), однофайловых +README/ADR (не персистентная база знаний), проекта без вики в mappa. + +## Три слоя (не смешивать) + +1. **Raw-источники** — `sources/` страницы. Иммутабельны: читай, не + редактируй (единственное исключение — блок-цитата `> Status` по явной + просьбе пользователя). +2. **Вики** — остальные страницы (entities/concepts/packages/contradictions/open-questions/overview). +3. **Схема** — сущности `AGENTS` (канон, slug `AGENTS`) + `CLAUDE` (legacy- + указатель «Canon is AGENTS»). Читай `AGENTS` первой; она перекрывает этот + скил при конфликте. + +## Первый шаг любой операции + +1. `mcp__mappa__wiki_get(project, 'AGENTS')` — если есть, читай (канон; если + нет — `wiki_get(project, 'CLAUDE')`, легаси-указатель). +2. `mcp__mappa__wiki_get(project, 'index')` — каталог; найди нужные страницы. + (Каталог по умолчанию — `entity_search`, решение 1; `index` — опора ориентации.) +3. Только потом действуй. + +Если `AGENTS`/`CLAUDE` нет — вики либо новая, либо неухоженная: не +импровизируй структуру, первый ingest создаёт `AGENTS` (+ `CLAUDE`-указатель). + +## MCP-поверхность + +| Операция | Тул | Примечание | +|---|---|---| +| Чтение страницы | `mcp__mappa__wiki_get(project?, slug)` | чтение — карв-аут (решение 19) | +| Поиск страниц | `mcp__mappa__entity_search(q, type='wiki', project?, scope?, limit)` | ILIKE по body/title | +| Лиз для записи | `mcp__mappa__task_claim_next(project, owner)` | → `token`; таска может отсутствовать | +| Продление лиза | `mcp__mappa__task_heartbeat(project, claim_token)` | долгие ingest-циклы | +| Создать страницу | `mcp__mappa__wiki_create(project, slug, body, claim_token)` | под лизом | +| Обновить страницу | `mcp__mappa__wiki_update(project, id, title?, body?, claim_token)` | под лизом; id — internal | +| Путь между сущностями | `mcp__mappa__graph_path({from, to})` | кратчайшая цепочка, BFS | +| Соседи / исходящие | `mcp__mappa__graph_neighbors({id})` | рёбра узла с резолвом целей | +| Входящие ссылки | `mcp__mappa__graph_backlinks({id})` | кто ссылается на узел | +| Здоровье графа | `mcp__mappa__graph_stats()` | nodes/edges/components | + +**Запись всегда под лизом.** Мутации wiki гейтятся лизом проекта: без +валидного `claim_token` — 422 busy. Лиз экспирится по TTL (дефолт 600s); +закрыть вручную нечем (кроме `admin_release_lease` для залипших) — пиши, +затем отпусти (не держи лиз на время чтения/размышлений). + +**Рефы и id (#1037/#1028).** Публичная поверхность несёт per-type реф полным +именем первым полем: `ref: "wiki:3"` (решение 20, конвенция #1028), `num` +следом, глобальный `id` — internal (последним). Для `wiki_update` нужен +internal `id` — из ответа `wiki_get`/`entity_search`. В прозе — слаг/имя +первым, реф как якорь: «спека `concepts/session-live-ingest` (wiki:2604)». +В теле страниц — викилинки по слагу (`[[concepts/foo]]`, решение 4) или +per-type рефы полными именами (`[[task:N]]`/`[[inbox:N]]`). + +--- + +## Цикл: три операции + +### Ingest — «заингесть X» + +1. Прочитай источник полностью. +2. Извлеки: entities, concepts, packages, кросс-резы. +3. Создай `sources/` — одну страницу-резюме на источник (~50–150 строк; + ссылку на raw клади в frontmatter `raw_path` + `ingested:`). +4. Для каждой затронутой страницы: + - есть → обнови (`wiki_update(project, id, body, claim_token)`). **Противоречия + помечай явно** блоком `> **Противоречие:** источник A говорит X, источник B — Y`. + Не затирай молча. + - нет → создай (`wiki_create`). +5. Обнови `index` (каталог: одна строка на страницу) — опционально; каталог + по умолчанию — `entity_search` (решение 1). +6. Отчитайся пользователю: что создано, что обновлено, какие противоречия. + Первый ingest новой вики: создай `AGENTS` (канон) + `CLAUDE` (указатель). + +**Оп-лог — автоматический.** Каждая write-операция уже пишется сервисом в +таблицу `logs` (component=тип сущности, message=slug+operation; смотреть — +`mcp__mappa__admin_logs`). Ручную `log`-страницу НЕ веди — это дубль, +аудит-след живёт в сервисе (решение 12, ратификация 2026-08-24). + +**Один ingest может затронуть 10–15 страниц. Это нормально — для того LLM и нужны.** + +Порядок записи: сначала лиз (`task_claim_next`), затем все wiki-мутации одним +циклом (не бери лиз на чтение), затем отпусти (лиз живёт TTL — просто закончи +писать; heartbeat только если цикл реально долгий). + +### Query — вопрос по вики + +1. Читай `index` сначала, затем углубляйся в страницы (`wiki_get` по слагу). +2. Отвечай с цитатами-викилинками: `[[concepts/foo]]` (рёбра создаются при + записи, решение 4). +3. **Компаундируй вики.** Если ответ — реальный синтез (сравнение, анализ, + новая связь) — спроси пользователя: «Сохранить как страницу wiki?» Хорошие + вопросы становятся страницами в `concepts/`. + +**Реляционные/структурные вопросы — не читай, а зови граф** (следующая секция): +связи образуют граф, который LLM не обходит надёжно чтением. + +### Lint — «проверь вики» + +Ищи: +- **Противоречия** между страницами. +- **Сирот** — страницы без входящих ссылок: `graph_backlinks(id)` (id из + `wiki_get`) → нет входящих рёбер = сирота. +- **Stale-claims** — `updated_at` страницы старше источника, который она резюмирует. +- **Потерянные сущности** — понятия из текста без своей страницы + (`entity_search` по имени → пусто). +- **Пустые/TODO-секции.** + +Отчёт — панч-лист. Ничего не удаляй автоматически. + +--- + +## Граф-слой (реляционные/структурные вопросы) + +**Stop and call the graph.** На реляционный/структурный вопрос о вики или +любых сущностях mappa (таски, письма, сессии) **не отвечай, прочитав одну +страницу** — это 0%-recall провал, ради которого существует граф-слой. +Сервис ходит по рёбрам детерминированно (BFS) и возвращает ответ в +нескольких строках; контекст не засоряется. + +Формы вопроса → тул: + +| Вопрос | Тул | +|---|---| +| relational — «что связывает X и Y», «путь между», "what connects", "shortest path" | `graph_path({from, to})` | +| neighbourhood — «соседи X», "neighbours of X" | `graph_neighbors({id})` | +| incoming — «кто ссылается на X», «backlinks», "what links to X" | `graph_backlinks({id})` | +| health — «сироты», «битые ссылки», «здоровье вики», "orphan pages" | `graph_stats()` + `graph_backlinks(id)` | + +**Адресация: slug → internal id.** Резолвь `id` через `wiki_get`/`entity_search` +(последнее поле ответа; `ref`/`num` — для показа). Ответы graph несут per-type +refs полными именами (`task:N`/`inbox:N`/`wiki:N`, конвенция #1028) — реферируй +по ним, не по id. Пустой `path` = связи реально нет — так и скажи; не выдумывай +цепочку из текстовой близости. + +**Precondition — граф реально связан.** Если сомневаешься — сначала +`graph_stats()`: `edges` ≈ 0 ⇒ граф пуст, отвечай чтением. (Слаги без +[[линков]] рёбер не создают; сироты — норма для разреженных вики.) + +--- + +## Форматы страниц (ОБЯЗАТЕЛЬНО) + +### Frontmatter + +```yaml +--- +title: Человекочитаемое имя +type: entity | concept | package | source | contradiction | open-question | overview +tags: [short, tokens] +sources: [concepts/mappa.md] +updated: 2026-08-24 +--- +``` + +Страницы `sources/` дополнительно несут `ingested: YYYY-MM-DD` и `raw_path: …`. +`contradictions/` — `status: open | resolved | accepted-divergence` и `affects:`. +`open-questions/` — `status: open | answered | obsolete` и `touches:`. + +### Слаги + +- `kebab-case`, **только латиница**. Кириллицу/др. скрипты транслитерируй + (`план переписывания` → `ozon-client-rewrite`). Оригинальный title — в H1 и frontmatter. +- `entities/`, `concepts/`, `packages/`, `sources/`, + `contradictions/`, `open-questions/`. + +### Оп-лог — таблица `logs`, не страница + +File-based `log.md` мёртв (решение 12/15, ратификация 2026-08-24). Сервис пишет +оп-лог сам при каждой write-операции: `mcp__mappa__admin_logs` (фильтры +level/since/component/entity, retention 14d). Ручную `log`-страницу не заводи, +не дописывай, не парси. + +### `index` — каталог через поиск + +Каталог = `entity_search(q, type='wiki', project)` (решение 1). `index`-страница +— опциональная опора для ориентации: одна строка на страницу +`- [Title](concepts/foo.md) — hook.`, секции по типам. Обновляй только если +страница уже существует; не плоди каталог-дубли. + +## Quick reference + +| Ситуация | Что трогаем | +|---|---| +| Ingest одного документа | `sources/` (новая) + 3–15 entities/concepts/packages (+ опционально `index`) | +| Query | (чтение) + возможно новая страница | +| Query реляционный | graph_* (BFS), не чтение | +| Lint | (чтение) + graph_backlinks/stats для сирот | +| Новая вики проекта | первый ingest создаёт `AGENTS` + `CLAUDE`-указатель; оп-лог — автоматический | + +## Частые ошибки + +- **Правка `sources/`.** Нельзя. Только статус-блок по явной просьбе. +- **Дамп сырья в `sources/`.** Резюме — это резюме. Ссылайся на raw, не копируй. +- **Молчаливые перезаписи.** Новый источник противоречит странице — пометь + блоком `> **Противоречие:**`; не затирай. +- **Нарративный оп-лог.** Не веди его руками: сервис пишет logs сам (admin.logs). +- **Не-ASCII слаги.** Ломают grep и кросс-платформенность. Транслитерируй. +- **Пропущенные противоречия в lint.** Ценность вики — во вскрытых напряжениях, + а не в ложном консенсусе. +- **Запись без лиза.** Wiki-мутации без `claim_token` → 422 busy. +- **Держать лиз на чтение/раздумья.** Лиз — на время записи. Чтение — карв-аут. +- **Реляционный вопрос чтением одной страницы.** Это тот самый 0%-recall + провал — зови graph_*. +- **Слаги/пути в graph-тулы.** Только internal id, и только свежие (удалённая + сущность → ошибка). +- **Тащить всю вики в контекст**, чтобы «проследить» связи руками — сервис + делает это за ноль токенов. + +## Red flags + +- Реляционный вопрос → читаешь страницу вместо `graph_*`. +- Правка `sources/` или молчаливая перезапись противоречия. +- Wiki-мутация без лиза (422) или лиз держится на чтение. +- Нарративный оп-лог руками. + +--- + +## Reference + +- Поиск по сущностям: `mcp__mappa__entity_search` (FTS, решение 1). +- Оп-лог: `mcp__mappa__admin_logs` (автоматический, решение 12). +- Дерево/зонтики: `mcp__mappa__graph_tree(root, depth?, fields?, limit?)`. +- Задачи: `mappa-task-work`. Почта: `mappa-messaging`. Делегирование: `mappa-delegation`. +- Related: `using-projects-meta` (мост до флипа), `project-discipline`. diff --git a/skills/using-wiki-graph/SKILL.md b/skills/using-wiki-graph/SKILL.md deleted file mode 100644 index 119a70d..0000000 --- a/skills/using-wiki-graph/SKILL.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -name: using-wiki-graph -author: ours -version: 1.1.0 -description: > - Use when a question is RELATIONAL about a wiki or any entities in Mappa — - «что связывает X и Y», «как связаны», «путь между X и Y», «what connects X - and Y», «shortest path» — or about STRUCTURE/HEALTH — «что ссылается на X», - «backlinks of X», «сироты», «битые ссылки», «orphan pages». Triggers - `mcp__mappa__graph_neighbors|graph_backlinks|graph_path|graph_stats` — - детерминированный BFS по рёбрам графа на стороне сервиса (решение 4/7: - [[refs]] в body → рёбра). Guarded failure-mode: на реляционные вопросы агент - читает одну страницу и ОСТАНАВЛИВАЕТСЯ, никогда не ходит по многохоповым - цепочкам сам. Адресация — internal id (из wiki_get/entity_search); ответы - несут per-type refs полными именами (task:N/inbox:N/wiki:N, решение 20/#1037, - конвенция #1028). Read-only, без лиза - (карв-аут, решение 19). Skip для одно-страничных контентных вопросов. ---- - -# using-wiki-graph - -Stop and call the graph. On a **relational** or **structural** question about -wiki-страницы или любые сущности mappa (таски, письма, сессии), не отвечай, -прочитав одну страницу — связи образуют граф, который LLM не обходит надёжно -чтением. Сервис ходит по рёбрам детерминированно (BFS) и возвращает ответ в -нескольких строках; контекст не засоряется. - -## When to use - -Вопрос о **связях между сущностями** или **структуре графа**, не о содержании -одной страницы: - -- relational — "what connects X and Y", "path between X and Y", «что связывает», - «как связаны», «путь между»; -- neighbourhood — "neighbours of X", «соседи X», «что рядом с X»; -- incoming — "what links to X", "who references X", «кто ссылается на X», - «backlinks»; -- health — "orphan pages", "dangling links", «сироты», «битые ссылки», - «здоровье вики». - -## Precondition — граф реально связан - -Граф полезен, когда рёбра есть. Если сомневаешься — сначала -`mcp__mappa__graph_stats()`: `edges` ≈ 0 ⇒ граф пуст, отвечай чтением. -(Слаги без [[линков]] рёбер не создают; сироты — норма для разреженных вики.) - -## Адресация: slug → id (internal) - -Тулы graph принимают **internal id** (SQL PK), который наружу помечен internal -(решение 20/#1037). Резолв: - -1. `mcp__mappa__wiki_get(project, slug)` (или `entity_search(q, type='wiki')`) — - из ответа бери `id` (последнее поле; публичные `ref`/`num` — для показа). -2. Передавай `id` в graph-тулы. -3. Ответы graph несут `ref` (task:N/inbox:N/wiki:N — полные имена, #1028) на - узлах и рёбрах (`from_ref`/`to_ref`) — реферируй по ним в ответе, не по id. - -## Steps - -1. Выбери тул по форме вопроса: - - relational / "what connects" → `mcp__mappa__graph_path({from, to})` — - кратчайшая неориентированная цепочка. - - neighbourhood → `mcp__mappa__graph_neighbors({id})` — исходящие рёбра - узла с резолвом целей (to_ref/kind). - - "who links to" → `mcp__mappa__graph_backlinks({id})` — входящие рёбра. - - health → `mcp__mappa__graph_stats()` (nodes/edges/components); сирота - конкретной страницы = `graph_backlinks(id)` пусто. -2. Резолвь id (см. выше), зови graph, отдавай цепочку/список как есть. -3. Пустой `path` = связи реально нет — так и скажи; не выдумывай цепочку - из текстовой близости. - -## Failure modes - -- Страница удалена/не найдена → graph тул вернёт ошибку. Проверь `wiki_get` — - возьми свежий id. -- Разреженный граф → `stats` показывает ~0 edges. Не форсируй — читай. -- Нет MCP-тулов mappa в сессии → граф недоступен; читай вручную, отметь - пользователю, что mappa MCP не подключён. - -## Side effects - -None. Read-only (карв-аут лиза, решение 19): без лиза, без записи, без сети -кроме сервиса. - -## What NOT to do - -- Не отвечай на реляционный вопрос чтением одной страницы — это тот самый - 0%-recall провал, ради которого скил существует. -- Не тащи всю вики в контекст, чтобы «проследить» связи руками — сервис делает - это за ноль токенов. -- Не зови graph на контентные вопросы ("что такое X") — это чтение, не граф. -- Не передавай слаги/пути в graph-тулы — только internal id, и только свежие - (удалённая сущность → ошибка). diff --git a/skills/using-wiki/README.md b/skills/using-wiki/README.md deleted file mode 100644 index 67d4c97..0000000 --- a/skills/using-wiki/README.md +++ /dev/null @@ -1,183 +0,0 @@ -# using-wiki - -Runtime policy for an LLM Wiki built on the -[Karpathy LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f). -Knowledge is **compiled once and kept current** across three layers, via -three named operations, with strict file formats that keep the wiki -parseable and grep-friendly. - -`using-wiki` governs *usage* of an existing `.wiki/`. Initial creation and -**Канал — mappa** (решение 14/15): вики = сущности `type=wiki` в сервисе -(см. SKILL.md v2.0.0). Файловый `.wiki/` — легаси; `setup-wiki` умер. - -> Renamed from `wiki-maintainer` at v1.0.0. - -## When it triggers - -- User says: "use project wiki", "query the wiki", "ingest this", or the - Russian equivalents ("обнови вики", "проверь вики", "запроси вики", - "заингесть"). -- Any time the agent modifies a file under `.wiki/` — the workflow and - formats below are mandatory. -- If `.wiki/` is missing or non-canonical, this skill delegates to - вики читается из mappa (`wiki_get`); ничего настраивать не нужно. - -## Three layers (do not blur) - -1. **Raw sources** — `.wiki/raw/` (or external paths registered in - `raw/README.md`). **Immutable.** Read, never edit. The only exception is - appending a `> Status` blockquote when the user explicitly asks for a - status audit. -2. **Wiki** — everything else under `.wiki/`. Agent-owned. Entity / concept / - package / source summary pages. -3. **Schema** — `.wiki/CLAUDE.md`. Project-specific conventions (what - entities, what packages, naming). Always read it first; it overrides this - skill on conflict. - -## Three operations - -### Ingest - -«заингесть X» — pull a raw source into the wiki. - -1. Read the raw source fully. -2. Extract: entities, concepts, packages, cross-cutting patterns. -3. Create `sources/.md` (one summary page per source, ~50–150 lines). -4. For each affected entity / concept / package page: update if exists, - create if not. Flag contradictions explicitly with - `> **Противоречие:** источник A говорит X, источник B — Y`. - **Never silently overwrite.** -5. Update `index.md`. -6. Append one line to `log.md`. -7. Report: what was created, updated, contradicted. - -One ingest may touch 10–15 pages. That's normal — that's why an LLM does it. - -### Query - -A question answered from the wiki. - -1. Read `index.md` first, drill into relevant pages. -2. Answer with citations as markdown links. -3. **Compound the wiki.** If the answer is a real synthesis, ask the user: - "Сохранить как страницу wiki?" Good queries become durable pages under - `concepts/` or `analyses/`. -4. Append one line to `log.md`. - -### Lint - -«проверь wiki» — health check. - -Scan for: - -- Contradictions between pages. -- Orphans (pages with no inbound links). -- Stale claims (raw source updated after the summary's `ingested:` date — - check via `git log -p`). -- Concepts mentioned in prose but missing their own page. -- Empty / TODO sections. - -Report as a punch list. Don't delete anything automatically. Append one -line to `log.md` with the findings. - -## File formats (mandatory) - -### Page frontmatter - -```yaml ---- -title: Человекочитаемое имя -type: entity | concept | package | source | contradiction | open-question | overview -tags: [short, tokens] -sources: [../sources/foo.md, ../sources/bar.md] -updated: 2026-04-21 ---- -``` - -Source pages also carry `ingested: YYYY-MM-DD` and `raw_path: ../raw/...`. -Contradiction pages also carry `status: open | resolved | accepted-divergence` and `affects: [../entities/x.md, ../concepts/y.md]`. -Open-question pages also carry `status: open | answered | obsolete` and `touches: [../entities/x.md, ../sources/z.md]`. - -### File naming - -- `kebab-case.md`, **Latin only**. Transliterate Cyrillic / non-Latin in - filenames; keep the original title in H1 + frontmatter. -- `entities/.md`, `concepts/.md`, `packages/.md` - (no `@org/` prefix), `sources/.md`, `contradictions/.md`, - `open-questions/.md`. - -### `log.md` — append-only, grep-parseable - -Every entry must start with: - -``` -## [YYYY-MM-DD] | -``` - -Operations: `ingest`, `query`, `lint`, `refactor`, `decision`, `init`. - -Parse with: `grep "^## \[" .wiki/log.md | tail -20`. - -### `index.md` - -Catalog, not narrative. One line per page: `- [Title](path) — hook.` -Sections by type. Update on every ingest. - -### Cross-references - -- Wiki → wiki: relative markdown links — `[Name](../entities/x.md)`. -- Wiki → code: relative path from repo root — `[foo.js](../../packages/api/foo.js)`. -- Wiki → raw: `../raw/`. -- URL-encode spaces (`%20`) and Cyrillic when needed. - -## Quick reference - -| Situation | Files touched | -|---|---| -| Ingest one doc | `sources/.md` (new) + 3–15 entity/concept/package pages + `index.md` + `log.md` | -| Query | (read only) + optionally a new wiki page + `log.md` | -| Lint | (read only) + `log.md` | -| Новая вики проекта | первый ingest создаёт CLAUDE/index/log через wiki_create | - -## Common mistakes - -- **Editing `raw/`.** Don't. Only allowed change: status blockquote on - explicit request. -- **Dumping raw content into `sources/`.** Summaries are summaries. Link to - raw, don't copy. -- **Silent overwrites on contradictions.** Flag them with a `> **Противоречие:**` - block. -- **Narrative `log.md`.** "Today I added…" is wrong. Use - `## [YYYY-MM-DD] ingest | `. -- **Non-ASCII filenames.** Breaks greppability and cross-platform. Transliterate. -- **Forgetting `index.md`.** Pages not listed there are invisible to future - queries. -- **Improvising layout when canon files are missing.** Hand off to - (setup-wiki умер: канал — mappa, страницы создаются wiki_create). - -## When NOT to use - -- The project has CLAUDE.md / AGENTS.md docs but no `.wiki/` — that's regular - documentation, not an LLM Wiki. -- The user wants a single-file README or ADR — this skill is for persistent, - interlinked knowledge bases. -- One-off questions about code — read files directly, no wiki workflow needed. - -## Install - -From the repo root: - -```bash -bash scripts/install.sh using-wiki -``` - -Works on Windows under git-bash, Linux, macOS. - -## See also - -- mappa — сервис-хост вики (`wiki.get`/`wiki.create`/`wiki.update`); - canon migration. -- [`project-bootstrap`](../project-bootstrap/) — invokes mappa-режим для - new projects. -- Karpathy's LLM Wiki gist: - diff --git a/skills/using-wiki/SKILL.md b/skills/using-wiki/SKILL.md deleted file mode 100644 index 7f09f2e..0000000 --- a/skills/using-wiki/SKILL.md +++ /dev/null @@ -1,217 +0,0 @@ ---- -name: using-wiki -author: ours -version: 2.2.0 -description: > - Policy skill for working with the project wiki in Mappa (Karpathy LLM Wiki - pattern, channel = mappa-сущности, решения 14/15 спеки mappa). Use when the - user asks to ingest a document, answer from the wiki, lint/health-check it, or - says «use project wiki», «обнови вики», «проверь вики», «запроси вики», - «заингесть», «query the wiki». Also use when modifying any wiki page — the - workflow and formats below are mandatory, and project-specific conventions live - in the `AGENTS` wiki-сущности проекта (legacy — `CLAUDE`-указатель). Wiki = - сущности `type=wiki` в сервисе - (чтение — карв-аут лиза; запись — под лизом проекта, решение 19). Файлового - `.wiki/` больше нет; `setup-wiki` умер (нечего настраивать). ---- - -# using-wiki - -> Policy for maintaining an LLM Wiki (Karpathy pattern: -> https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) whose pages -> live in **Mappa** as `type=wiki` сущности (решение 14/15), not in files. -> Knowledge is **compiled once and kept current**: three named operations -> (ingest / query / lint), strict page formats that keep the wiki parseable and -> grep-friendly, and a cross-linked graph ([[refs]] → рёбра, решение 4). - -## Prerequisites - -Wiki проекта = сущности в сервисе Mappa (HTTP-ядро, MCP-адаптер `mcp__mappa__*`). -Слаг страницы = путь от корня вики без расширения (`index`, `log`, `AGENTS`, -`CLAUDE`, `concepts/foo`, `entities/bar`, `packages/baz`, `sources/doc`, `overview`). -Body = frontmatter + markdown как есть (content-модель сохраняется, решение 2). - -Проектная вики (scope=project) читается/пишется с параметром проекта; -общая вики (scope=shared) — без проекта. Чей именно вики трогаем, определяет -контекст: `wiki.get(project, slug)` — проектная, `wiki.get(slug)` — shared. - -Файловый `.wiki/` в репозиториях — легаси: источник истины — сервис. -Если вики проекта пуста (нет сущностей) — **ничего настраивать не надо** -(setup-wiki умер): первый ingest сам создаёт `AGENTS` (+ `CLAUDE`-указатель); -оп-лог вести не нужно — сервис пишет его в таблицу `logs` автоматически -(решение 12, ратификация 2026-08-24). - -## MCP-поверхность - -| Операция | Тул | Примечание | -|---|---|---| -| Чтение страницы | `mcp__mappa__wiki_get(project?, slug)` | чтение — карв-аут лиза (решение 19) | -| Поиск страниц | `mcp__mappa__entity_search(q, type='wiki', project?, scope?, limit)` | ILIKE по body/title | -| Захват лиза для записи | `mcp__mappa__task_claim_next(project, owner)` | → `token` (лиз проекта, решение 19); таска может отсутствовать | -| Продление лиза | `mcp__mappa__task_heartbeat(project, claim_token)` | долгие ingest-циклы | -| Создать страницу | `mcp__mappa__wiki_create(project, slug, body, claim_token)` | под лизом | -| Обновить страницу | `mcp__mappa__wiki_update(project, id, title?, body?, claim_token)` | под лизом; id — internal (см. ниже) | - -**Запись всегда под лизом.** Мутации wiki гейтятся лизом проекта: без -валидного `claim_token` — 422 busy. Лиз экспирится по TTL (дефолт 600s); -закрыть вручную нечем (кроме `admin_release_lease` для залипших) — пиши, -затем отпусти (не держи лиз на время чтения/размышлений). - -**Рефы и id (#1037/#1028).** Публичная поверхность несёт per-type реф первым полем: -`ref: "wiki:3"` (полное имя типа + номер, решение 20, конвенция #1028), `num` -следом, глобальный `id` — internal (последним полем). Для `wiki.update` нужен -internal `id` — бери его из ответа `wiki_get`/`entity_search`. В тексте страниц -ссылайся викилинками по слагу (`[[concepts/foo]]`, решение 4) или per-type -рефами полными именами (`[[inbox:N]]`/`[[task:N]]`). В прозе — слаг/имя первым, -реф как якорь: «спека `concepts/session-live-ingest` (wiki:2604)». - -## Три слоя (не смешивать) - -1. **Raw-источники** — `sources/` страницы. Иммутабельны: читай, не - редактируй (единственное исключение — блок-цитата `> Status` по явной - просьбе пользователя). -2. **Вики** — все остальные страницы (entities/concepts/packages/…). -3. **Схема** — сущности `AGENTS` (канон, slug `AGENTS`) + `CLAUDE` (legacy- - указатель «Canon is AGENTS»). Конвенции проекта. Читай `AGENTS` первой; она - перекрывает этот скил при конфликте. - -## Первый шаг любой операции - -1. `mcp__mappa__wiki_get(project, 'AGENTS')` — если есть, читай (канон; если - нет — `wiki_get(project, 'CLAUDE')`, легаси-указатель). -2. `mcp__mappa__wiki_get(project, 'index')` — каталог, найди нужные страницы. -3. Только потом действуй. - -Если `AGENTS`/`CLAUDE` нет — вики либо новая, либо неухоженная: не -импровизируй структуру, создай `AGENTS` (+ `CLAUDE`-указатель) при первом -ingest (см. ниже). Каталог — через `entity_search` (решение 1); `index`-страница -опциональна (для ориентации). - -## Три операции - -### Ingest — «заингесть X» - -1. Прочитай источник полностью. -2. Извлеки: entities, concepts, packages, кросс-резы. -3. Создай `sources/` — одну страницу-резюме на источник (~50–150 строк; - ссылку на raw клади в frontmatter `raw_path` + `ingested:`). -4. Для каждой затронутой страницы: - - есть → обнови (`wiki_update(project, id, body, claim_token)`). **Противоречия - помечай явно** блоком `> **Противоречие:** источник A говорит X, источник B — Y`. - Не затирай молча. - - нет → создай (`wiki_create`). -5. Обнови `index` (каталог: одна строка на страницу) — опционально; каталог - по умолчанию — `entity_search` (решение 1). -6. Отчитайся пользователю: что создано, что обновлено, какие противоречия. - Первый ingest новой вики: создай `AGENTS` (канон) + `CLAUDE` (указатель). - -**Оп-лог — автоматический.** Каждая write-операция уже пишется сервисом в -таблицу `logs` (component=тип сущности, message=slug+operation; смотреть — -`mcp__mappa__admin_logs`). Ручную `log`-страницу НЕ веди — это дубль, -аудит-след живёт в сервисе (решение 12, ратификация 2026-08-24). - -**Один ingest может затронуть 10–15 страниц. Это нормально — для того LLM и нужны.** - -Порядок записи: сначала лиз (`task_claim_next`), затем все wiki-мутации одним -циклом (не бери лиз на чтение), затем отпусти (лиз живёт TTL — просто закончи -писать; heartbeat только если цикл реально долгий). - -### Query — вопрос по вики - -1. Читай `index` сначала, затем углубляйся в страницы (`wiki_get` по слагу). -2. Отвечай с цитатами-викилинками: `[[concepts/foo]]` (рёбра создаются при - записи, решение 4). -3. **Компаундируй вики.** Если ответ — реальный синтез (сравнение, анализ, - новая связь) — спроси пользователя: «Сохранить как страницу wiki?» Хорошие - вопросы становятся страницами в `concepts/`. - -Оп-лог в query — автоматический (logs-таблица); строку вручную не дописывай. - -### Lint — «проверь вики» - -Ищи: -- **Противоречия** между страницами. -- **Сирот** — страницы без входящих ссылок: `mcp__mappa__graph_backlinks(id)` - (id из `wiki_get`) → нет входящих рёбер = сирота (подробнее — using-wiki-graph). -- **Stale-claims** — `updated_at` страницы старше источника, который она резюмирует. -- **Потерянные сущности** — понятия из текста без своей страницы - (`entity_search` по имени → пусто). -- **Пустые/TODO-секции.** - -Отчёт — панч-лист. Ничего не удаляй автоматически. -Оп-лог в lint — автоматический (logs-таблица); строку вручную не дописывай. - -## Форматы страниц (ОБЯЗАТЕЛЬНО) - -### Frontmatter - -```yaml ---- -title: Человекочитаемое имя -type: entity | concept | package | source | contradiction | open-question | overview -tags: [short, tokens] -sources: [concepts/mappa.md] -updated: 2026-08-24 ---- -``` - -Страницы `sources/` дополнительно несут `ingested: YYYY-MM-DD` и `raw_path: …`. -`contradictions/` — `status: open | resolved | accepted-divergence` и `affects:`. -`open-questions/` — `status: open | answered | obsolete` и `touches:`. - -### Слаги - -- `kebab-case`, **только латиница**. Кириллицу/др. скрипты транслитерируй - (`план переписывания` → `ozon-client-rewrite`). Оригинальный title — в H1 и frontmatter. -- `entities/`, `concepts/`, `packages/`, `sources/`, - `contradictions/`, `open-questions/`. - -### Оп-лог — таблица `logs`, не страница - -File-based `log.md` мёртв (решение 12/15, ратификация 2026-08-24). Сервис пишет -оп-лог сам при каждой write-операции: `mcp__mappa__admin_logs` (фильтры -level/since/component/entity, retention 14d). Ручную `log`-страницу не заводи, -не дописывай, не парси. - -### `index` — каталог через поиск - -Каталог = `entity_search(q, type='wiki', project)` (решение 1). `index`-страница -— опциональная опора для ориентации: одна строка на страницу -`- [Title](concepts/foo.md) — hook.`, секции по типам. Обновляй только если -страница уже существует; не плоди каталог-дубли. - -## Quick reference - -| Ситуация | Что трогаем | -|---|---| -| Ingest одного документа | `sources/` (новая) + 3–15 entities/concepts/packages (+ опционально `index`) | -| Query | (чтение) + возможно новая страница | -| Lint | (чтение) | -| Новая вики проекта | первый ingest создаёт `AGENTS` + `CLAUDE`-указатель; оп-лог — автоматический | - -## Частые ошибки - -- **Правка `sources/`.** Нельзя. Только статус-блок по явной просьбе. -- **Дамп сырья в `sources/`.** Резюме — это резюме. Ссылайся на raw, не копируй. -- **Молчаливые перезаписи.** Новый источник противоречит странице — пометь - блоком `> **Противоречие:**`; не затирай. -- **Нарративный оп-лог.** Не веди его руками: сервис пишет logs сам (admin.logs). - «Сегодня я добавил…» — даже вручную писать не надо. -- **Не-ASCII слаги.** Ломают grep и кросс-платформенность. Транслитерируй. -- **Забытый `index`.** Страницы без записи в каталоге невидимы для будущих query - (если index-страница ведётся; дефолтный каталог — entity_search). -- **Пропущенные противоречия в lint.** Ценность вики — в вскрытых напряжениях, - а не в ложном консенсусе. -- **Запись без лиза.** Wiki-мутации без `claim_token` → 422 busy; не пытайся - писать «напрямую». -- **Держать лиз на чтение/раздумья.** Лиз — на время записи. Чтение — карв-аут. - -## Когда НЕ использовать этот скил - -- Проект без вики в mappa (нет сущностей `type=wiki`) — обычная документация, - не LLM Wiki. -- Пользователь хочет однофайловый README/ADR — скил для персистентной - связной базы знаний. -- Разовые вопросы по коду — обычное чтение файлов, не вики-воркфлоу. -- Реляционные/структурные вопросы о вики (связи, сироты, пути) — это - **using-wiki-graph** (`mcp__mappa__graph_*`).