- 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
19 KiB
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С-проекты):
- Прочитать
claude/memory/1c/README.md— там протокол - Листинг
configurations/иprojects/— увидеть актуальный набор - Прицельно 2–3 релевантных файла
- Параллельно — skill
1c-analystдля процедурных знаний (как делать); vault — для «что у пользователя конкретно есть и как»
Если запрос подразумевает генерацию документа (приказ, ТЗ, регламент, проектная документация, типовое письмо) — дополнительно:
- Прочитать
claude/memory/1c/files/list.md— это реестр шаблонов - Если в таблице есть подходящий по смыслу шаблон — скачать файл
через Gitea raw-endpoint, открыть через соответствующий skill
(
docx/xlsx/pdf-reading), использовать как основу - Если подходящего шаблона нет — сгенерировать с нуля, в конце
предложить пользователю сохранить результат в
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. В начале содержательного разговора
Если разговор касается проекта/системы/темы, по которым у пользователя может быть накопленный контекст:
- Проверить домен. Если это маркетинг/продажи UCN — СТОП,
переключиться на
ucnl-market-memoryskill. - Поиск по теме. Content-поиск по vault через API:
Альтернатива для поиска по frontmatter-полю — grep по всем файлам в
GET /api/v1/repos/creator/obsidian-vault/search?q=<keyword>&type=codeclaude/memory/projects/:GET /api/v1/repos/creator/obsidian-vault/contents/claude/memory/projects - Читаем top-3..5 самых релевантных. Приоритет: свежесть (
updated), явныйprojectmatch, высокийrelevance. Исключитьprivate: trueиз ответов (но прочитать можно). - Использовать контекст в ответе естественно, без меты про «я нашёл заметку...».
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)
content, неcontent_base64. ВPOST /contents(включая batch) поле называетсяcontent. Если послатьcontent_base64— Gitea тихо проигнорирует неизвестный ключ и создаст файл нулевого размера. Файл «появится», коммит пройдёт, а содержимое будет пустое.- URL-encode путей. Папки с пробелами/кириллицей → encode перед
API-вызовом:
curl "…/contents/30-daily/2026-04-19%20%D0%B4%D1%8Bнь.md". PUTтребуетshaтекущей версии. Забыл sha — получишь 409. Всегда перечитывать перед update'ом.- Новый репо «пустой» после
auto_init=true. Первый commit через API создаёт initial commit и ветку main. До этого момента API?ref=mainвозвращает 404. - 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, ASCIIclaude/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-memoryskill.