CLAUDE.md · diff

git:20261002.27ef1f8 to git:20261002.3394cc4

1 added, 0 removed. Audit A to A.

# Knowledge
Личная база экспертизы по дизайну интерфейсов и тексту: скиллы с универсальными правилами, которые не привязаны ни к одному проекту. Ими пользуются в проектах (правила читаются на каждом изменении интерфейса и текста), на приёмке, в консультациях, воркшопах и в преподавании. Проект ставит скиллы и держит у себя только свои решения.
## Где что лежит
В `skills/` лежит то, что агент применяет без оговорок. Недоделанное и записи редакции лежат в `working/`: папка не входит в скилл, и её правила не применяются. Она публикуется вместе с репозиторием, чтобы спорное и недоделанное можно было обсудить в Issues.
| Файл | О чём | Когда меняется |
| --- | --- | --- |
| `skills/nickture-interface/SKILL.md` | фронтматтер, вступление, как читать, разделы, экспресс-проход | при звезде правила, новом файле в `rules/` и правке вступления |
| `skills/nickture-interface/rules/*.md` | правила интерфейса, файл на раздел: принципы, что желательно определить, типографика, цвет, пространство, иерархия, иконки, формы, состояния, навигация, онбординг, компоненты, мобильная версия, графики, документы, почта, доступность, прокрутка, движение, производительность, слоп | при новом правиле или источнике, при уточнении правил |
| `skills/nickture-interface/sources.md`, `skills/nickture-text-ru/sources.md` | источники и их ключи, у каждого скилла своя таблица | при новом источнике |
| `skills/nickture-text-ru/SKILL.md` | фронтматтер, вступление, разделы и вводный абзац слопа | при новом файле в `rules/` и правке вступления |
| `skills/nickture-text-ru/rules/*.md` | правила письма, файл на раздел: заголовки, порядок, кто говорит, единообразие, утверждения, слова, числа, слоп (приёмы, шум, стоп-слова, текст целиком), типографика, формы, подписи в интерфейсе, сообщения, переписка, мета, как проверять | при новом правиле или уточнении существующих |
| `working/interface/disputed.md`, `working/text/disputed.md` | спорные правила, вынесенные на доработку | при выносе правила на доработку и при его возврате |
| `working/interface/disagreements.md`, `working/text/disagreements.md` | где источники расходятся и что выбрано | при споре источников |
| `working/interface/rejected.md` | что из источников сознательно не взяли, с причиной | при отказе от совета источника |
| `working/interface/process.md` | как проверять интерфейс, готовить и показывать работу; до переработки | при переработке |
| `working/interface/landing.md` | лендинг и страница тарифов; после доработки разложится на сценарии | при новом правиле или переработке |
| `working/interface/patterns.md`, `working/text/patterns.md` | приёмы убеждения и тёмные паттерны; до доработки | при новом паттерне или источнике |
| `working/text/english.md` | правила и маркеры только для английского текста, основа английской версии | при английском признаке в новом источнике |
| `README.md` | что это, установка, как запускать, обновление, участие, лицензия | при новом скилле и способе установки |
| `CONTRIBUTING.md` | куда присылать ошибки, правила и источники, лицензия присланного | при новом способе участия |
| `.github/ISSUE_TEMPLATE/*.yml` | формы Issues: ошибка или спор в правиле, новое правило, новый источник | при новом скилле: он добавляется в выпадающий список |
| `.claude-plugin/marketplace.json` | каталог плагинов Claude Code, плагин на скилл | при новом скилле |
| `LICENSE` | текст CC BY 4.0 | не меняется |
| `AGENTS.md` | симлинк на этот файл, чтобы правила правки читали Codex, Cursor и другие агенты | не меняется |
## Как проект пользуется скиллами
- **Правила универсальные, Foundation проектный.** В проекте может лежать свой Foundation: ответы на раздел «Что желательно определить» (гарнитуры, цвета, шкалы, `z-index`, длительности) и исключения с причинами. Общие правила там не повторяются, на них ссылаются по заголовку.
- **Правило можно нарушить с причиной.** Причина записывается в Foundation проекта рядом с исключением.
## Правила правки
- **Ни проекта, ни клиента, ни продукта.** В скиллах не называются проекты, клиенты, продукты и люди из разборов. Примеры обобщаются: «карточка товара», «экран выбора тарифа». Называются только авторы источников в таблице ключей и в тексте правила, где мысль принадлежит им.
- **Формат правила.** `` - **Заголовок.** ★ Утверждение. Почему. Пример или число. `[ключ]` ``. Заголовок коротко называет правило, описание после него объясняет, что проверять и почему. Tailwind utility class в скобках необязателен и ставится в правиле про код как подсказка реализации. В `nickture-text-ru` пример стоит под строкой правила врезкой `>` из двух абзацев: «Плохо:» и «Хорошо:». Заголовок уникален в своём скилле и не меняется без нужды: на него ссылаются проекты.
- **Фильтр перед записью.** Правило проверяемо, верно для любого продукта своего типа, у него есть причина, и оно не дублирует уже записанное. Дубль сливается с существующим правилом, ключи источников складываются.
- **★ — экспресс-проход, около сорока правил.** Звезда ставится правилу, которое ловит самую заметную ошибку на экране. Новая звезда — повод снять другую. Заголовки правил со звездой повторяются списком в разделе «Экспресс-проход» в `skills/nickture-interface/SKILL.md`. Звезда ставится и снимается сразу в обоих местах.
- **Источник указан ключом.** Новый источник сначала получает строку в `sources.md` своего скилла, источник обоих скиллов стоит в обеих таблицах. Ключ из записи в `working/interface/` или `working/text/` тоже стоит в таблице своего скилла. Собственные разборы и мысли автора идут под ключом `nick`.
- **Спор источников решается явно.** Если источники советуют разное, правило записывается по выбранному варианту, а сам спор — строкой в `working/interface/disagreements.md` или `working/text/disagreements.md`. Спор без выбора записывается с пустой колонкой «Выбрано», и правило по нему не пишется. Не взятое целиком — в `working/interface/rejected.md` с причиной.
- **Текст к тексту, интерфейс к интерфейсу.** Подписи, ошибки, числа и тон — в `skills/nickture-text-ru/rules/`. Вёрстка, состояния и компоненты — в `skills/nickture-interface/rules/`. Скиллы ссылаются друг на друга и не повторяют друг друга.
- **Правило лежит в файле своего раздела.** Новое правило записывается в файл раздела в `rules/`, новый раздел заводит новый файл и строку в разделе «Разделы» своего `SKILL.md`. Правило из другого файла называется заголовком в кавычках, ссылкой на этот файл оформлен заголовок без кавычек: `по правилу «[Дай нажать](principles.md)»`. Правило другого скилла называется заголовком и именем скилла без ссылки, `` по правилу «Регистр как в предложении» скилла `nickture-text-ru` ``: скиллы ставят по одному, и путь в соседний скилл может никуда не вести.
- **Недоделанное лежит в `working/`.** Спорное правило переезжает в `working/interface/disputed.md` или `working/text/disputed.md` с пометкой, что с ним не так. Доработанное правило или документ возвращается в скилл. Скилл на `working/` не ссылается.
- **Скиллы пишутся по правилам `nickture-text-ru`.** Русский язык, термины как есть (`hover`, `focus-visible`, `ease-out`), стоп-слова в переносном смысле не используются, «не X, а Y» не чаще раза на 750 слов, в предложении одно тире или двоеточие.
+ - **Страницы GitHub на английском.** `README.md`, `CONTRIBUTING.md` и формы Issues пишутся на английском, их читают и те, кто не знает русского. Скиллы, `working/` и этот файл остаются на русском, и README прямо говорит, что скиллы пока на русском.
## Проверки
Все команды из корня репозитория. Пустой вывод — хорошо.
```bash
I=skills/nickture-interface; T=skills/nickture-text-ru
# экспресс-проход совпадает со звёздами правил
diff <(grep -ohE '^- \*\*[^*]+\*\* ★' $I/rules/*.md | sed -E 's/^- \*\*(.+)\*\* ★$/\1/' | LC_ALL=C sort) \
<(awk '/^## Экспресс-проход/{p=1; next} /^## /{p=0} p && /^- /' $I/SKILL.md | sed 's/^- //' | LC_ALL=C sort)
# заголовки правил уникальны в своём скилле
grep -ohE '^- \*\*[^*]+\*\*' $I/rules/*.md | LC_ALL=C sort | LC_ALL=C uniq -d
grep -ohE '^- \*\*[^*]+\*\*' $T/rules/*.md | LC_ALL=C sort | LC_ALL=C uniq -d
# у каждого правила интерфейса есть ключ источника
grep -hE '^- \*\*' $I/rules/*.md | grep -vE '`\[[a-z-]+(, [a-z-]+)*\]`$'
# «не X, а Y»: не больше одного на 750 слов
echo "лимит $(( $(cat $I/rules/*.md | wc -w) / 750 )), найдено $(cat $I/rules/*.md | grep -oE '(^|[ «(])не [^,.:;!?]{1,60}, а |, а не ' | wc -l)"
# три тире или двоеточия в одном предложении
grep -nE '( — |: )[^.!?…]*( — |: )[^.!?…]*( — |: )' $I/rules/*.md
# стоп-слова в переносном смысле (каждое вхождение проверяется глазами)
grep -noiE '(держит|держится|живёт|несёт|спорит| уходит|упирается|поверх[ .,:;]|тих[аиоуеыя]|раньше|жд[её]т|ждут|спеш)' $I/rules/*.md
# каждый использованный ключ есть в источниках своего скилла, записи из working/ тоже
for a in interface text; do s=$I; [ $a = text ] && s=$T
comm -23 <(grep -ohE '`\[[a-z-]+(, [a-z-]+)*\]`' $s/SKILL.md $s/rules/*.md working/$a/*.md \
| tr -d '`[]' | tr ',' '\n' | tr -d ' ' | LC_ALL=C sort -u) \
<(grep -oE '^\| `[a-z-]+`' $s/sources.md | tr -d '| `' | LC_ALL=C sort -u) | sed "s|^|$a: |"
done
# фронтматтер: первая строка ---, name совпадает с папкой, description до 1024 знаков
for f in skills/*/SKILL.md; do n=${f#skills/}; n=${n%/SKILL.md}
[ "$(head -1 $f)" = "---" ] || echo "$n: нет фронтматтера"
grep -qx "name: $n" $f || echo "$n: name не совпадает с папкой"
l=$(sed -n 's/^description: //p' $f | head -1 | tr -d '\n' | wc -m); [ $l -gt 0 ] && [ $l -le 1024 ] || echo "$n: description $l знаков"
done
# каждый файл rules/ есть в разделах своего SKILL.md
for f in skills/*/rules/*.md; do grep -q "](rules/${f##*/})" ${f%/rules/*}/SKILL.md || echo "нет в разделах: $f"; done
# ни одна ссылка не выходит из своего скилла
grep -rnE '\]\((\.\./)+nickture-' skills
# ёлочки стоят вне ссылки, кроме плохих примеров
grep -rnE '\[«|»\]\(' README.md CONTRIBUTING.md skills working | grep -v '> Плохо:'
# каждый скилл есть в каталоге плагинов
for d in skills/*/; do grep -q "\"./${d%/}\"" .claude-plugin/marketplace.json || echo "нет в marketplace.json: $d"; done
# каждый скилл есть в выпадающих списках форм Issues
for d in skills/*/; do n=$(basename $d)
for f in .github/ISSUE_TEMPLATE/0[12]-*.yml; do grep -qx " - $n" $f || echo "нет в $f: $n"; done
done
# у правила текста есть врезка с примером: должны остаться ровно пять меточных правил
awk 'FNR==1 { if (h != "" && !got) print h; h=""; got=0 }
/^- \*\*/ { if (h != "" && !got) print h; h=$0; got=0; next }
/^ > Хорошо:/ { got=1 }
/^#/ { if (h != "" && !got) print h; h=""; got=0 }
END { if (h != "" && !got) print h }' $T/rules/*.md | sed -E 's/^- \*\*([^*]+)\*\*.*/\1/'
```
```bash
# служебное для проверок ниже: вырезать цитаты — код, ссылки, номера стандартов,
# строки «Плохо» и всё в кавычках. Плохой пример в правилах иллюстрирует нарушение,
# а не совершает его. Номера строк сохраняются: sed затирает содержимое, не строки
cite() { sed -E 's/`[^`]*`//g; s/\]\([^)]*\)//g; s/ГОСТ [0-9.]+-[0-9]+//g; s/«[^»]*»//g; s/„[^“]*“//g; s/^( *> Плохо:).*/\1/' "$1"; }
ADJ='настоящ|следующ|предыдущ|будущ|текущ|общ|недостающ|подходящ|соответствующ'
for f in README.md CONTRIBUTING.md skills/*/*.md skills/*/rules/*.md working/interface/process.md working/*/patterns.md working/*/disagreements.md working/interface/rejected.md; do
# канцелярит: пустой глагол, отглагольное существительное, служебное слово
cite "$f" | grep -noiE '(^|[^а-яё])(осуществл|производит(ся)?[ ,.]|имеет место|носит [а-яё]+ характер|данн(ый|ая|ое|ого|ому|ом)|указанн(ый|ая|ое)|в целях|в случае если|при наличии|не представляется возможным)' | sed "s|^|канцелярит $f:|"
# цепочка родительных падежей: три существительных подряд
cite "$f" | grep -noiE '[а-яё]+(ения|ания|ации) +[а-яё]+(ения|ания|ации|ов|ий) +[а-яё]+(ения|ания|ации|ов|ий)' | sed "s|^|родительные $f:|"
# два причастия в одном предложении, кроме похожих на них прилагательных
cite "$f" | grep -noE '[а-яё]+(ущ|ющ|ащ|ящ|вш|ем|им)(ий|ая|ее|ие|его|ей|их)[^.!?…]*[а-яё]+(ущ|ющ|ащ|ящ|вш|ем|им)(ий|ая|ее|ие|его|ей|их)' | grep -viE "$ADJ" | sed "s|^|причастия $f:|"
# усилители: «ровно то» и «реально» наречием. «Ровно» перед числом и «реальный»
# против выдуманного законны, поэтому в выражение они не попадают. «Именно» и «как раз»
# названы в правиле, но не ищутся: у них бывает различающая работа
cite "$f" | grep -noiE '(^|[^а-яё])(ровно (то|тот|та|те|так|это|этот)([^а-яё]|$)|реально([^а-яё]|$))' | sed "s|^|усилитель $f:|"
# «без» с оценкой, ощущением или чужим инструментом. Хороший пример учит так же, как правило,
# поэтому строки «Хорошо» не вырезаются. «Без ручного X» и «без скрытых комиссий» бывают законны и не ищутся
sed -E '/^ *> Хорошо:/!s/«[^»]*»//g; s/`[^`]*`//g; s/^( *> Плохо:).*/\1/' "$f" | grep -noiE '(^|[^а-яё])без (лишн|ненужн|уловок|хлопот|головной боли|догад|рутин|суеты|усилий|сторонн)' | sed "s|^|без $f:|"
# «поэтому» рядом с «это»: «поэтому» составлено из «по этому», и пара звучит как повтор
cite "$f" | grep -noiE '(^|[^а-яё])(поэтому эт|эт(о|а|и|от|у)( [а-яё]+){0,2},? поэтому)' | sed "s|^|поэтому $f:|"
# механическая типографика: три точки, прямые кавычки, дефис между цифрами, «стр.», «8-ми», «90-х гг.», повтор №,
# стрелка, «≈», знак предупреждения и линия из символов рамки вместо слова
cite "$f" | grep -noE '(\.\.\.|"[^"]*"|[0-9]-[0-9]|[0-9]+-(ми|та|тил)|стр\. ?[0-9]|[0-9]{2,4}-х гг\.|№ ?[0-9]+, ?№|→|≈|⚠|─)' | sed "s|^|типографика $f:|"
done
```
## Git
- Коммит только по просьбе, push только по просьбе.
- Сообщение коммита на английском, заголовок и тело. Один коммит — одно изменение: новое правило отдельно от переформулировки, дизайн отдельно от текста.
- Ветка `main`, историю не переписываем.