Files
claude-skills/obsidian-memory/SKILL.md
T
creator 8213ff750a claude: sync ucnl-market-memory and obsidian-memory skills
- rewrite ucnl-market-memory/SKILL.md with final layout (accounts/products/campaigns/markets + insights/conversations/inbox), extended frontmatter (sensitive flag), domain routing table with border examples
- refresh obsidian-memory/SKILL.md with the same domain-routing section placed at top, matching examples, and updated description with negative trigger
2026-04-20 14:10:04 +03:00

19 KiB
Raw Blame History


name: obsidian-memory description: Protocol for using creator/obsidian-vault (Gitea repo at h3fq32.golive.ru) as Claude's long-term memory for personal and R&D projects of Arthur Abelentsev. Trigger when the user references past work ("my X project", "we decided Y", "remember that..."), asks Claude to remember/save/update/forget something, mentions a project by name (lotus-eletre, uspeak-trademark, homework-, 1c-, pcb-, obsidian, claude-skills), or whenever a substantive insight, decision, or fact surfaces that's worth preserving between sessions. Covers personal context, infrastructure (gitea/traefik/mikrotik/xray), embedded firmware, PCB design, 1C consulting for any client, R&D on UCN products (acoustics, firmware, algorithms), legal/trademark work, travel, vehicle/hardware, and general life. Also covers answering non-trivial project questions that benefit from previously stored context. Describes vault layout, frontmatter conventions, Gitea REST API mechanics (read/list/search/create/update), naming rules, and write permissions. Do NOT trigger for: simple one-off technical questions or casual chat that doesn't involve the user's ongoing projects. Do NOT trigger for UCN marketing/sales commercial work (clients, distributors, quotes, exhibitions, pricing, product marketing for uWave/Zima2/uSpeak) — that is handled by a separate ucnl-market-memory skill and a separate repo (ucnlmarket/ucnl-market-memory).

obsidian-memory

Протокол работы с creator/obsidian-vault как долговременной памятью. Vault — обычный git-репо в Gitea, хранит markdown-заметки с YAML-frontmatter. Claude читает и пишет заметки через Gitea REST API.

Разграничение доменов — прочитать первым

У пользователя два репо памяти с жёстким разделением:

Домен Репо Скилл
Личные проекты Артура, инфраструктура, embedded, 1С-консалтинг (любые клиенты), R&D по UCN-продуктам, legal/trademark, быт creator/obsidian-vault этот скилл
Маркетинг и продажи UCN (клиенты, дистрибьюторы, выставки, КП, экспорт, product marketing uWave/Zima2/uSpeak/USBL) ucnlmarket/ucnl-market-memory ucnl-market-memory

Правило жёсткое: материалы из одного домена НЕ попадают в репо другого. Если тема пограничная — спросить пользователя, не додумывать.

Примеры границы:

Запрос Куда
«Прошивка uWave — обновить через STM32CubeProg» R&D → этот скилл
«Письмо Mavi Marine по срокам поставки» sales UCN → ucnl-market-memory
«Расчёт TDOA для uWave USBL» R&D/алгоритмы → этот скилл
«Слайд для INNOPROM KSA 2026» маркетинг UCN → ucnl-market-memory
«ТЗ на 1С для Teplovin» 1С не-UCN → этот скилл
«Скидка дистрибьютору X» sales UCN → ucnl-market-memory

«UCN как клиент внутреннего 1С-проекта» — дефолт этот скилл (технический слой), но с коммерческой частью (бюджет, контракт) — уточнить.

Where things live

  • Gitea: https://git.h3fq32.golive.ru
  • Repo: creator/obsidian-vault
  • Branch: main
  • Access: bash_tool + curl с Authorization: token $GITEA_TOKEN

Токен должен быть в окружении ($GITEA_TOKEN) или в сессионном контексте. Если ни там, ни там его нет — попросить пользователя один раз в начале, в последующих вызовах использовать.

Vault layout

00-inbox/              user's raw notes, READ-ONLY for Claude
10-projects/           active projects (lotus-eletre/, uspeak/, …), READ-ONLY
20-knowledge/          reference (1c/, embedded/, infrastructure/), READ-ONLY
30-daily/              daily log, meetings, READ-ONLY
claude/                Claude's own space, READ-WRITE
├── memory/
│   ├── facts.md       stable facts (one file, append-only section)
│   ├── preferences.md user preferences and standards
│   ├── projects/
│   │   └── <slug>.md  cumulative per-project context
│   └── 1c/            отдельная область: 1С-экосистема пользователя
│       ├── README.md            протокол + конвенции именно для 1С
│       ├── configurations/      КА, ERP, УТ, ЗУП — по конфигурациям
│       ├── projects/            клиентские 1С-внедрения
│       └── files/               шаблоны и эталонные документы
│           ├── README.md
│           └── list.md          реестр: имя файла ↔ описание
├── insights/          dated observations: YYYY-MM-DD-<slug>.md
├── conversations/     session summaries: YYYY-MM-DD-<slug>.md
└── inbox/             drafts for user review

Areas vs projects: claude/memory/projects/ — разовый контекст одного проекта в одном файле. claude/memory/<area>/ — целая тематическая область со своей подструктурой. Сейчас такая есть одна (1c/), могут появиться ещё (embedded/, infrastructure/ если разрастётся из facts.md). Решение «один файл vs целая папка» принимается по тому, нужна ли внутренняя структура (конфигурации, клиенты, паттерны) — если да, это область.

1С — special case

В начале любого разговора, где всплывают 1С-темы (конфигурации КА/ERP/УТ/ЗУП, внедрения, BSL-код, интеграции с Bitrix24, ТЗ на 1С-проекты):

  1. Прочитать claude/memory/1c/README.md — там протокол
  2. Листинг configurations/ и projects/ — увидеть актуальный набор
  3. Прицельно 2–3 релевантных файла
  4. Параллельно — skill 1c-analyst для процедурных знаний (как делать); vault — для «что у пользователя конкретно есть и как»

Если запрос подразумевает генерацию документа (приказ, ТЗ, регламент, проектная документация, типовое письмо) — дополнительно:

  1. Прочитать claude/memory/1c/files/list.md — это реестр шаблонов
  2. Если в таблице есть подходящий по смыслу шаблон — скачать файл через Gitea raw-endpoint, открыть через соответствующий skill (docx/xlsx/pdf-reading), использовать как основу
  3. Если подходящего шаблона нет — сгенерировать с нуля, в конце предложить пользователю сохранить результат в files/ как новый шаблон (тогда одним коммитом: файл + строка в list.md)

Важно: файл в files/ без строки в list.md для Claude не существует. При любом добавлении/обновлении — реестр дописывается.

Write rule: Claude пишет только в claude/**. Всё остальное — read-only. Если кажется что стоит дополнить 20-knowledge/… — положить в claude/inbox/ с пометкой «proposed addition to » и отдать пользователю на ревью.

Frontmatter

Каждый файл в claude/** начинается с YAML-frontmatter:

---
type: memory | insight | conversation | fact | preference
project: <slug>              # опционально; lotus-eletre, uspeak, и т.п.
tags: [<tag1>, <tag2>]       # свободная форма, kebab-case
created: YYYY-MM-DD
updated: YYYY-MM-DD
relevance: 0.0-1.0           # оценка важности, используется при ранжировании
confidence: low | medium | high
private: false               # true → не использовать в ответах, не упоминать наличие
sources:                     # опционально: откуда знание пришло
  - conversation: 2026-04-19-lotus-yaw-calibration
  - url: https://…
---

private: true — сильное правило. Такие заметки читать можно (для понимания контекста пользователя), но в ответах не цитировать, не ссылаться, и не упоминать факт их существования.

Protocol

1. В начале содержательного разговора

Если разговор касается проекта/системы/темы, по которым у пользователя может быть накопленный контекст:

  1. Проверить домен. Если это маркетинг/продажи UCN — СТОП, переключиться на ucnl-market-memory skill.
  2. Поиск по теме. Content-поиск по vault через API:
    GET /api/v1/repos/creator/obsidian-vault/search?q=<keyword>&type=code
    
    Альтернатива для поиска по frontmatter-полю — grep по всем файлам в claude/memory/projects/:
    GET /api/v1/repos/creator/obsidian-vault/contents/claude/memory/projects
    
  3. Читаем top-3..5 самых релевантных. Приоритет: свежесть (updated), явный project match, высокий relevance. Исключить private: true из ответов (но прочитать можно).
  4. Использовать контекст в ответе естественно, без меты про «я нашёл заметку...».

2. Когда НЕ искать

  • Простые технические вопросы без персонального контекста («как в Python отсортировать список по ключу»)
  • Разговорная болтовня, приветствия
  • Одноразовые операции
  • Вопросы, где пользователь сам дал весь нужный контекст в сообщении
  • Темы маркетинга/продаж UCN — это не сюда

3. В процессе разговора

  • При упоминании сущностей, имеющих свою заметку в vault, использовать [[wiki-links]] в новых заметках (пригодится для навигации в Obsidian)
  • Если обнаружилось противоречие между памятью и тем что говорит пользователь сейчас — честно сказать («в заметках было X, сейчас Y — обновить?»), не тихо исправлять

4. В конце содержательного разговора

Если всплыли значимые инсайты / факты / решения — сохранить:

Что появилось Куда класть
Одноразовое наблюдение по проекту claude/insights/YYYY-MM-DD-<slug>.md
Накопительный контекст по проекту (обновляется) claude/memory/projects/<slug>.md
Стабильный факт общего характера claude/memory/facts.md (append в секцию)
Предпочтение пользователя claude/memory/preferences.md
Выжимка самой беседы claude/conversations/YYYY-MM-DD-<slug>.md
Сомневаешься куда — claude/inbox/ + explicit note пользователю

Не писать ради галочки. Лучше 0 файлов, чем пять пустословных. Критерий: «если через полгода другой instance Claude прочитает эту заметку — она ему что-то даст?».

Gitea REST API — шпаргалка

GITEA=https://git.h3fq32.golive.ru
REPO=creator/obsidian-vault
TOKEN=$GITEA_TOKEN    # или подставить вручную

# ── READ ────────────────────────────────────────────────────────────────────

# Прочитать файл (raw содержимое)
curl -sS -H "Authorization: token $TOKEN" \
  "$GITEA/api/v1/repos/$REPO/raw/claude/memory/facts.md"

# Листинг папки (metadata всех файлов)
curl -sS -H "Authorization: token $TOKEN" \
  "$GITEA/api/v1/repos/$REPO/contents/claude/memory/projects?ref=main" \
  | python3 -c "import sys,json; [print(x['path'], x['size']) for x in json.load(sys.stdin)]"

# Content-поиск (требует включённый индекс на уровне инстанса Gitea)
curl -sS -H "Authorization: token $TOKEN" \
  "$GITEA/api/v1/repos/$REPO/search?q=eletre+alignment&type=code"

# Tree (вся структура целиком с recursive)
curl -sS -H "Authorization: token $TOKEN" \
  "$GITEA/api/v1/repos/$REPO/git/trees/main?recursive=true"

# ── WRITE ───────────────────────────────────────────────────────────────────

# Создать новый файл (POST contents). Содержимое — base64.
content_b64=$(base64 -w0 /tmp/note.md)
curl -sS -X POST -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  "$GITEA/api/v1/repos/$REPO/contents/claude/insights/2026-04-19-foo.md" \
  -d "{
    \"message\": \"claude: insight on X\",
    \"content\": \"$content_b64\",
    \"branch\": \"main\"
  }"

# Обновить существующий файл (PUT, нужен sha текущей версии)
sha=$(curl -sS -H "Authorization: token $TOKEN" \
  "$GITEA/api/v1/repos/$REPO/contents/claude/memory/facts.md?ref=main" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])")
content_b64=$(base64 -w0 /tmp/facts-new.md)
curl -sS -X PUT -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  "$GITEA/api/v1/repos/$REPO/contents/claude/memory/facts.md" \
  -d "{
    \"message\": \"claude: update facts — add Eletre calibration notes\",
    \"content\": \"$content_b64\",
    \"sha\": \"$sha\",
    \"branch\": \"main\"
  }"

# Batch (несколько файлов одним коммитом) — POST contents БЕЗ пути
curl -sS -X POST -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  "$GITEA/api/v1/repos/$REPO/contents" \
  -d '{
    "branch": "main",
    "message": "claude: session summary with 2 artefacts",
    "files": [
      {"operation":"create", "path":"claude/conversations/…", "content":"<b64>"},
      {"operation":"update", "path":"claude/memory/projects/…", "content":"<b64>", "sha":"<prev-sha>"}
    ]
  }'

Gotchas (learned the hard way)

  1. content, не content_base64. В POST /contents (включая batch) поле называется content. Если послать content_base64 — Gitea тихо проигнорирует неизвестный ключ и создаст файл нулевого размера. Файл «появится», коммит пройдёт, а содержимое будет пустое.
  2. URL-encode путей. Папки с пробелами/кириллицей → encode перед API-вызовом: curl "…/contents/30-daily/2026-04-19%20%D0%B4%D1%8Bнь.md".
  3. PUT требует sha текущей версии. Забыл sha — получишь 409. Всегда перечитывать перед update'ом.
  4. Новый репо «пустой» после auto_init=true. Первый commit через API создаёт initial commit и ветку main. До этого момента API ?ref=main возвращает 404.
  5. Rate limit. По умолчанию Gitea не агрессивен, но batch-операции предпочтительнее N одиночных запросов — один коммит лучше для истории и дешевле по HTTP.

Commit message format

Все коммиты Claude в vault — префикс claude::

  • claude: save <тема> from conversation — новая заметка
  • claude: update <путь> — <что именно> — правка
  • claude: merge <откуда> → <куда> — переорганизация
  • claude: remove <путь> — <причина> (редко; чаще private: true)

Это позволяет пользователю легко фильтровать git log | grep ^claude: и понять что делал Claude в vault.

Naming

  • claude/insights/YYYY-MM-DD-<slug>.md — slug kebab-case, ASCII
  • claude/conversations/YYYY-MM-DD-<slug>.md — аналогично
  • claude/memory/projects/<slug>.md — slug совпадает с 10-projects/<slug>/ если проект существует
  • claude/memory/<topic>.md — accumulating files (facts, preferences)

Русские названия → транслит или короткий англ. эквивалент. лотос-настройка-развалаlotus-alignment.

Boundaries

  • Не писать в пользовательские папки (00–30). Если нужно предложить изменение — в claude/inbox/ с пометкой.
  • Не удалять пользовательские файлы никогда. Свои (claude/**) — можно, если очевидно устарело; предпочтительнее private: true чем удаление (история сохраняется в git, но из выдачи исчезает).
  • Не обходить private: true. Такие заметки не цитировать и не упоминать.
  • Честно флагить противоречия между тем что в vault и что говорит пользователь, не исправляя молча.
  • Не писать в ucnlmarket/ucnl-market-memory из этого контекста. Если тема всплыла UCN-sales — переключиться на ucnl-market-memory skill.