Lint
Ревьюер Obsidian wiki-vault. Запускает статические проверки + script auto-fixes, затем агентские проверки (Layer 2) и LLM-fix'ы, в конце ведёт диалог с пользователем по оставшимся ask-issues. Единственный owner всего post-detection пайплайна — вызывается напрямую (`/lint`) или из ingest в конце synthesis-цикла. Триггеры: /lint, "lint", "проверка здоровья", "очисти wiki", "проверь wiki", "найди сирот", "wiki audit".From its SKILL.md
npx -y skills add matvej-melikhov/karpathy-llm-wiki --skill lintAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
23.9 KB, ~6.4k tokens by cl100k_base, as published. Nobody here has run it
lint: пайплайн ревью wiki
Lint — единственный owner всего пайплайна обработки issues. Когда скилл вызван (пользователем напрямую или из ingest), он:
- Запускает
bin/static_lint.py(Layer 1 + script auto-fixes inline). - Запускает Layer 2 — LLM-семантические проверки.
- Применяет agent auto-fixes (
missing-summary,domain-order,tag-casing). - Ведёт диалог с пользователем по оставшимся ask-issues.
- Перезаписывает
lint-state.jsonфинальным состоянием.
После выполнения: либо все issues разрешены (open_issues пуст), либо остались явно отложенные пользователем («позже»).
Итоговый отчёт (всегда первым в чате)
После Step 1 и Step 4 (то есть когда уже понятна суммарная статистика по авто-фиксам) — выдай одну строку сводки ещё до ask-диалога:
Lint завершён. Script auto-fix: 5 (inline-tags×2, non-canonical-wikilink×2, missing-summary handled by agent). Agent auto-fix: 1 (missing-summary). Ask: 2.
Правила:
-
Сводка — одна строка, в формате «N (тип×k, тип×k, …)» для каждой категории. Если в категории один issue —
типбез ×k. -
Источник script-фиксов —
lint-state.json::applied_script_fixes. Это список{type, where}, собранный скриптом за этот запуск. -
Если applied_script_fixes пуст — пиши «Script auto-fix: 0» или вообще опусти эту часть.
-
Если хочешь дать полный список «что и где» — оборачивай в
<details>, чтобы не загромождать чат:<details> <summary>Что было автоматически исправлено</summary> - inline-tags → wiki/ideas/X.md - inline-tags → wiki/ideas/Y.md - non-canonical-wikilink → wiki/entities/Z.md … </details> -
Если open_issues пуст и applied_script_fixes пуст — короткое «wiki чистая, изменений не было», без таблиц.
Дальше — ask-диалог по оставшимся issues, как обычно.
Pipeline
Step 1. Запустить bin/static_lint.py
python3 bin/static_lint.py # --quick (default)
python3 bin/static_lint.py --full # full audit
Скрипт сам делает:
- skip-check (если wiki не менялась и нет накопленных issues — пропуск)
- детект 13 типов issues (Layer 1) + 2 embedding-based (Layer 1.5)
- inline применение script auto-fixes для всех script-fixable типов
- запись
lint-state.jsonс remaining issues (agent-fix + ask + skip)
Embedding-based проверки (similar-but-unlinked, synthesis-drift,
contradiction_candidates) запускаются всегда, если есть wiki/meta/embeddings.json.
Если эмбеддингов нет (embedder недоступен) — warning + skip только этих
checks, остальные работают.
В режиме --quick (по умолчанию) скрипт фильтрует scope: новые issues
эмитятся только для touched pages (контент-хеш изменился с прошлого lint),
старые issues для не-touched сохраняются. В --full scope не ограничен.
Step 2. Прочитать lint-state.json
Получить:
open_issues— всё что не пофиксил скриптcontradiction_candidates(опц.) — пары для Layer 2
Если open_issues пуст и contradiction_candidates нет — pipeline закончен,
ничего больше делать не нужно. Сообщить пользователю «wiki чистая».
Step 3. Layer 2 — LLM-проверки
См. секцию «Layer 2» ниже. Дописывает свои issues в open_issues (в памяти,
запись на диск только в Step 6).
Step 4. Agent auto-fixes
Для issues типа missing-summary, domain-order, tag-casing (см. секцию
«Agent auto-fixes» ниже) применить LLM-генерируемые правки. Удалить
применённые из open_issues.
Step 5. Ask-dialogue
Оставшиеся ask-issues спросить у пользователя одним батчем (см. «Ask-dialogue»).
По каждому ответу применить соответствующее действие, удалить из open_issues.
Issues с ответом «отложить» остаются в open_issues.
Step 6. Записать финальное состояние
Если в Step 3-5 что-то поменялось — пересчитать wiki_hash и записать
lint-state.json с обновлённым open_issues. Иначе оставить как есть.
Layer 2: LLM-проверки
Layer 2 запускается этим скиллом после Layer 1+1.5. Каждая проверка ниже — самостоятельное задание: дано что найти, формат issue, граничные случаи. Способ исполнения (как читать страницы, в каком порядке, в одном батче или нескольких) — на твоё усмотрение. Используй доступные артефакты (перечислены в каждой секции) и применяй естественный triage.
domain-order
Цель: в поле domain: домены должны быть упорядочены от частного к
общему. Первый = primary classification, используется для раскраски в
knowledge map.
Что НЕ флагуем:
- Параллельные/cross-cutting домены без иерархии:
[Machine Learning, Knowledge Management]— оба корневые, иерархии нет. - Один домен — упорядочивать нечего.
Issue format:
{
"type": "domain-order",
"where": "wiki/ideas/PPO.md",
"current": ["Machine Learning", "Reinforcement Learning"],
"expected": ["Reinforcement Learning", "Machine Learning"],
"reasoning": "RL ⊂ ML"
}
Это знание о мире (RL — поддомен ML), а не структурное свойство wiki. Скриптовые подсчёты member-pages ломаются на молодой wiki, поэтому LLM.
tag-casing
Цель: теги во frontmatter с правильным регистром. Аббревиатуры
uppercase (ML, RL, IR, NLP, RLHF), обычные слова TitleCase
(Code, Optimization, Alignment).
Что флагуем:
- Lowercase аббревиатуры:
ml→ML,rl→RL. - Lowercase обычные слова:
optimization→Optimization. - Очевидные опечатки регистра:
mL→ML.
Что НЕ флагуем:
- Уже-uppercase аббревиатуры:
ML,RL,IR,RLHF. - Capitalized обычные слова:
Code,Optimization,Math,Alignment. - Канонические аббревиатуры с нестандартным регистром:
LoRA,MapReduce,KMeans.
Issue format (один issue на тег):
{
"type": "tag-casing",
"where": "wiki/ideas/X.md",
"current": "ml",
"expected": "ML",
"reasoning": "ML — аббревиатура (Machine Learning)"
}
contradiction
Цель: найти пары страниц с прямо противоречивыми утверждениями (одна говорит X, другая ¬X на ту же тему).
Что НЕ контрадикция:
- Дополняющие утверждения («A это X», «A также Y»).
- Утверждения на разные подтемы.
- Несогласованности в формулировках без логического противоречия.
Доступные артефакты:
lint-state.json::contradiction_candidates— список пар, отфильтрованный Layer 1.5 по cosine similarity. Это primary entry point — пары, у которых даже теоретически может быть противоречие. Если поле есть — начинай отсюда.- Если нет (эмбеддинги не доступны) — построй кандидатов сам через topic-overlap (общие домены, общие теги, упоминания друг друга).
Issue format:
{
"type": "contradiction",
"page_a": "wiki/ideas/A.md",
"page_b": "wiki/ideas/B.md",
"claim": "<одно предложение про что они расходятся>"
}
outdated-claim
Цель: утверждение в более старой странице опровергнуто более новой.
Проверяй только пары где даты updated: различаются и темы пересекаются.
Можно использовать те же contradiction_candidates. Дополнительная
эвристика: A.updated < B.updated, B содержит явное «X has been replaced»,
«Y is no longer recommended», «previously, but now» паттерны.
Issue format:
{
"type": "outdated-claim",
"where": "wiki/ideas/A.md",
"claim": "<устаревшее утверждение в A>",
"conflicts_with": "wiki/ideas/B.md"
}
missing-concept
Цель: концепция упомянута в ≥3 разных content-страницах, но своей wiki-страницы у неё нет — кандидат на создание.
Что считается «упоминанием»:
- Capitalized one-word terms (аббревиатуры, имена методов):
GAE,LoRA,BERT. - Multi-word concepts:
Monte Carlo,Temporal Difference Learning,Markov Decision Process.
Что НЕ считается упоминанием:
- Wikilinks (
[[GAE]]) — отдельный case, ловитсяdead-link. - Code blocks (fenced
или inlinecode) — это примеры/код, не нарратив. - Meta-страницы (
wiki/cache.md,wiki/log.md,wiki/index.md).
Threshold: 3 разных страницы (не 3 упоминания). Повторное упоминание в одной странице не накручивает.
Доступная эвристика: Bash-grep по capitalized phrases, sort | uniq -c, top кандидатов — дешёвый pre-filter. Дальше LLM судит «реальный концепт достойный страницы или общеупотребительное слово».
Issue format:
{
"type": "missing-concept",
"term": "GAE",
"mentioned_in": ["wiki/ideas/PPO.md", "wiki/ideas/TD Learning.md",
"wiki/ideas/Advantage Function.md"]
}
Agent auto-fixes
Применяются автоматически (без вопросов пользователю), но требуют LLM.
missing-summary
Контент-страница без summary: во frontmatter (либо summary: "").
Действие:
- Прочитать страницу целиком.
- Сгенерировать саммари ≤120 символов: одно декларативное предложение, что это и зачем. Без отсылок к источнику, без «эта страница описывает...».
- Вписать в frontmatter одинарными YAML-кавычками:
summary: 'текст'. Двойные кавычки только если внутри есть одинарная. Внутри текста допустимы:,$,\, диакритика — одинарные кавычки безопасны. - На следующем Stop-hook'е
bin/gen_index.pyподхватит саммари вwiki/index.md. - Удалить issue из
open_issues.
Если страница пустая (нет body) — взять тему из заголовка/aliases, описать максимально кратко.
domain-order
Issue эмитится Layer 2 (см. выше), здесь применяем.
Действие:
- Прочитать
domain:блок из frontmatterwhere. - Переписать в порядке из
expected(массив имён в правильном порядке). - Сохранить wikilink-формат (
"[[Domain Name]]") — поменять только порядок. - Удалить issue из
open_issues.
tag-casing
Issue эмитится Layer 2 (см. выше), применяем здесь.
Действие:
- Прочитать
tags:массив изwhere. - Заменить
currentнаexpected. - Удалить issue из
open_issues.
Ask-dialogue
Оставшиеся issues (тип ≠ auto-fix и ≠ agent-fix) спросить у пользователя одним батчем. Категории см. в таблице ниже.
Формат вопроса
Lint нашёл проблемы, требующие решения:
1. [dead-link] [[SFT]] упомянута в [[RLHF]], страницы нет.
→ создать заглушку / убрать ссылку / отложить?
2. [orphan] [[Foo Bar]] никем не упомянута.
→ удалить / слинковать с [[X]] / отложить?
3. [missing-concept] "GAE" в [[PPO]], [[TD Learning]], [[Advantage]].
→ создать idea-страницу / отложить?
4. [contradiction] [[A]] и [[B]] (similarity 0.87): <claim>
→ разрешить (какая страница права?) / отложить?
5. [asymmetric-related] [[A]] → [[B]], но [[B]] не ссылается на [[A]].
→ симметризовать / удалить одностороннюю / отложить?
6. [similar-but-unlinked] [[PPO]] и [[Policy Gradient]] (cosine 0.87)
семантически близки, но wikilink между ними отсутствует.
→ связать в обе стороны / связать в одну / игнорировать / отложить?
7. [synthesis-drift] [[RLHF]] (drift 0.42) сильно отклонилась от
эмбеддинга своих источников. Возможна галлюцинация.
→ перечитать страницу и сравнить с источником / отложить?
Действия по ответам
- «Создать [[X]]» (
dead-link,missing-concept) → создать stub-страницу по_templates/idea.md(илиentityесли контекст указывает) с минимальным содержанием, удалить issue. - «Убрать ссылку» (
dead-link) → удалить wikilink из тела родительской страницы, удалить issue. - «Удалить» (
orphan) → удалить файл целиком, удалить issue. - «Слинковать с [[X]]» (
orphan) → дописать wikilink на текущую страницу в подходящую родительскую (выбратьXагентски), удалить issue. - «Симметризовать» (
asymmetric-related) → дописать[[A]]вrelated:страницы B, удалить issue. - «Удалить одностороннюю» (
asymmetric-related) → удалить[[B]]изrelated:страницы A, удалить issue. - «Создать domain» (
dangling-domain-ref) → создатьwiki/domains/<missing_domain>.mdиз_templates/domain.mdс минимальным описанием, удалить issue. - «Убрать domain» (
dangling-domain-ref) → удалить[[<missing_domain>]]из поляdomain:страницы, удалить issue. - «Связать обе» (
similar-but-unlinked) → добавить[[B]]вrelated:A И[[A]]вrelated:B, удалить issue. - «Связать одну» (
similar-but-unlinked) → спросить направление, добавить wikilink вrelated:соответствующей страницы, удалить issue. - «Игнорировать» (
similar-but-unlinked) → удалить issue (могут быть параллельные сущности, связь не нужна). - «Разрешить» (
contradiction,outdated-claim) → агент применяет правильное утверждение к одной из страниц или к обеим, удалить issue. - «Перечитать» (
synthesis-drift) → прочитать страницу + связанные[[raw/...]], сверить, при необходимости обновить, удалить issue. - «Отложить» / «позже» → оставить issue в
open_issues. Снова всплывёт при следующем/lint.
Несколько issues разом
Пользователь может ответить пачкой («1 — создать, 2 — отложить, 3, 4 — симметризовать»). Применить каждый ответ к соответствующему issue.
Категории issues
Каждый issue имеет type — категория определяет, на каком шаге pipeline он
обрабатывается.
Script auto-fix (Step 1, inline в static_lint.py)
Применяется самим скриптом, не доходит до lint-скилла. Перечислено для контекста.
type | Условие | Структура issue |
|---|---|---|
status-not-in-enum | status не из evaluation/in-progress/ready | {type, where, value, fix} |
invalid-fields | frontmatter не соответствует _templates/<type>.md. Subtype extra (удалить поле) или missing (добавить с default из шаблона) | {type, where, subtype, field} |
inline-tags | tags: [a, b] инлайн вместо block YAML | {type, where} |
raw-link-with-extension | [[raw/X.md]] вместо [[raw/X]] | {type, where, link} |
raw-ref-in-body | [[raw/...]] в теле страницы | {type, where, link, line} |
folder-type-mismatch | wiki/<X>/ vs type: рассогласованы | {type, where, current_type, expected_type} |
non-canonical-wikilink | path-prefixed [[wiki/ideas/X]] вместо [[X]] | {type, where, link, fix, context} |
binary-source-outside-formats | бинарь в raw/ вне raw/formats/ | {type, where, suggested} |
Agent auto-fix (Step 4)
Требует LLM (генерация контента или семантическое суждение). См. секцию выше.
type | Условие | Структура |
|---|---|---|
missing-summary | content-страница без summary: | {type, where, page_type} |
domain-order | LLM-issue, см. Layer 2 | {type, where, current, expected, reasoning} |
tag-casing | LLM-issue, см. Layer 2 | {type, where, current, expected, reasoning} |
Ask user (Step 5)
Требует решения пользователя.
type | Условие | Структура |
|---|---|---|
dead-link | wikilink на несуществующую страницу | {type, where, what, context} |
orphan | страница без входящих wikilinks | {type, where} |
missing-concept | концепция в ≥3 страницах без своей page | {type, term, mentioned_in} |
contradiction | противоречие двух страниц | {type, page_a, page_b, claim} |
outdated-claim | утверждение опровергнуто более новой | {type, where, claim, conflicts_with} |
dangling-domain-ref | domain: на несуществующую domain-страницу | {type, where, missing_domain} |
asymmetric-related | A.related → B без B.related → A | {type, page_a, page_b} |
similar-but-unlinked | две страницы близки, wikilink отсутствует (если эмбеддинги доступны) | {type, page_a, page_b, similarity, threshold} |
synthesis-drift | страница ушла далеко от центроида источников (если эмбеддинги доступны) | {type, where, drift, threshold} |
Skip
Информационные флаги, не спрашиваем:
type | Условие |
|---|---|
style-nit | стилистические замечания (не декларативное настоящее, отсутствие линка на не-ключевую сущность) |
Команда и флаги
| Команда | Поведение |
|---|---|
/lint | --quick (default): skip-check по wiki_hash; новые issues эмитятся только для touched pages (контент-хеш изменился с прошлого lint); старые issues для не-touched сохраняются. Embedding checks (similar-but-unlinked, synthesis-drift) запускаются всегда если есть wiki/meta/embeddings.json. |
/lint --full | Полный audit. Skip-check игнорируется, scope не ограничен. Используется periodically для глубокой проверки (раз в неделю, или после массового рефактора). |
Touched detection: wiki_hash сохраняется как aggregate, page_hashes —
per-page sha256. На первом запуске после миграции state'а bootstrap трактует
все страницы как touched (де-факто = --full).
Конвенции wiki
См. CLAUDE.md раздел Frontmatter — схема, типы, поля. Здесь не дублируем.
Что lint не делает
- Не лезет в
raw/. raw-источники иммутабельны (кроме transcript-конвертации черезtranscribe). - Не правит content-файлы по ask-issues самостоятельно. Только после явного решения пользователя.
- Не запускает синтез. Это работа
ingest. lint только чинит. - Не удаляет файлы без явного «удалить» от пользователя (на orphan).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.