Community연구 & 데이터 분석github.com

MinorBaek/wiki-lint

과학 마크다운 위키(Obsidian 호환)를 위한 진단 및 복구 도구 모음: 링크, 출처, 프론트매터, 표, 인코딩, 합성 블록 및 씰에 대한 33가지 건강 검사를 제공합니다.

wiki-lint란 무엇인가요?

wiki-lint는 과학 연구 위키(Obsidian 호환)의 건강 상태를 점검하고 복구하는 도구입니다. Python 표준 라이브러리로 작성되어 Windows, macOS, Linux에서 동일하게 실행되며, 33가지 검사를 통해 고아 문서, 깨진 링크, 프론트매터 오류, 표 불일치, 인코딩 문제 등을 탐지합니다. 모든 검사 규칙은 `wiki.config.json` 파일에 설정되어 있어 위키가 발전해도 코드를 수정할 필요가 없으며, 3,000개 노트 규모에서도 빠르게 실행됩니다. 이 도구는 Cursor 및 Codex와 같은 AI 개발 환경에서 위키 품질을 유지하는 데 특히 유용하며, 읽기 전용 진단과 함께 선택적 복구 기능(fix.py)을 제공하여 인덱스 제안, 백링크 추가, 드래프트 승격 등을 지원합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/MinorBaek/science-wiki-kit/tree/HEAD/skills/wiki-lint

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

wiki-lint은(는) 무엇을 하나요?

최초 실행 전, 키트 내 docs/GOTCHAS.md를 읽으십시오(알려진 거짓 양성, 운영 참고 사항).

위키(wiki.config.json의 wiki_root)에 대한 읽기 전용 건강 검사와 세 가지 복구 도구를 제공합니다. 모든 코드는 Python 표준 라이브러리로 작성되어 Windows, macOS, Linux에서 동일하게 실행됩니다. 모든 위키별 규칙(폴더, 상태 분류, 필드 맵, 예외, 동사 목록, 플레이스홀더 패턴, 임계값)은 설정 파일에 있으므로, 위키에 새로운 필드, 폴더 또는 검사가 추가되어도 로직은 변경되지 않습니다. 3,000개 이상의 노트 규모에서도 빠르게 동작하도록 설계되었습니다(전체 실행은 몇 초, 단 Check 13은 해당 규모에서 약 30초 소요).

관련 기술

  • wiki-ingest, wiki-ingest-book: 이 기술이 검사할 노트를 작성합니다(상태 결정 및 인덱스 라우팅에 동일한 설정 사용).
  • wiki-synthesize: Check 15가 작업 목록을 생성하고, Check 32가 씰을 감사합니다.
  • vocabulary-update: Check 30에 대한 해결 도구입니다.

레이아웃

skills/wiki-lint/
  SKILL.md
  scripts/
    lint.py        # 검사 실행 (--only, --out-dir, --self-test)
    fix.py         # 복구 도구: 인덱스 제안, Check 12 백링크, 드래프트 승격
  references/
    check-origins.md   # 각 검사가 존재하는 이유 (단일 권위)
    cli-reference.md   # 플래그, 설정 키, 출력 파일, 보고서 형식
wikikit/lint/        # 구현: context.py, checks_*.py, fixes.py, defaults.json
tests/fixtures/lint/ # 모든 검사를 실행하는 합성 미니 위키 + expected_counters.txt

각 사실 종류가 위치하는 곳(중복 금지): references/check-origins.md = 검사가 존재하는 이유; 이 파일 = 수행하는 작업; wikikit/lint/checks_*.py = 구현 방법; tests/fixtures/lint/expected_counters.txt = 픽스처 값이 그렇게 설정된 이유. 실행 후 도구는 발생한 각 검사에 대해 check-origins.md 포인터를 출력하므로, 적중이 실제 오류인지 잡음인지 판단할 때 동기를 알 수 있습니다.

엔지니어링 불변 규칙 (위반 금지)

  1. 모든 파일 I/O는 wikikit.textio를 통해 수행 (바이트 수준 UTF-8, BOM 없음, 줄 끝 변경 금지). 기본 newline 처리가 포함된 텍스트 모드 open()을 절대 사용하지 마십시오: CRLF 파일을 해당 방식으로 읽고 다시 쓰면 자동으로 변환됩니다.
  2. CRLF가 포함될 수 있는 텍스트에 대해 $와 함께 멀티라인 정규식을 절대 사용하지 마십시오: $는 CR과 LF 사이에 위치하여 쌍을 분리합니다. 줄 단위로 편집하십시오 (frontmatter.set_key, fixes._insert_backlinks).
  3. 설정이 단일 진실 공급원입니다. 위키에 필드, 폴더, 상태 또는 예외가 추가되면 wiki.config.json(lint 섹션)을 편집하고, 코드를 수정하지 마십시오. 기본값은 wikikit/lint/defaults.json에 있습니다.
  4. 스텁 예외는 균일합니다. lint.stub_exempt_checks는 status: stub 노트를 건너뛰는 검사 번호를 나열합니다. 설정에서 목록을 읽고, 절대 본문에서 다시 기술하지 마십시오. Check 10과 11은 인라인으로 스텁을 제외합니다(파일 시스템 개수).
  5. 플레이스홀더 탐지는 비해결시에만 적용됩니다. 볼트 인덱스에서 대상이 확인되는 위키링크는 이름이 패턴과 일치하더라도 절대 플레이스홀더로 플래그되지 않습니다. 정당한 ALL-CAPS 약어 노트는 플래그되지 않아야 합니다.
  6. 로직 변경 전 자체 테스트를 수행하십시오. 검사에 대한 모든 편집(새 검사, 임계값 변경, 휴리스틱 리팩토링)은 반드시 통과해야 합니다: python skills/wiki-lint/scripts/lint.py --self-test. 변경이 의도된 경우 tests/fixtures/lint/와 expected_counters.txt를 함께 업데이트하십시오. 픽스처가 차별화됨을 증명하십시오: 로직 변경을 되돌리고 재실행하여 카운터가 이동하는지 확인하십시오. 변경 전후 모두 통과하는 픽스처는 아무것도 보호하지 않습니다.
  7. 0은 위키의 측정값이 아니라 탐지기의 측정값입니다. 새 검사의 0을 신뢰하기 전에 양성 사례를 주입하고 플래그가 발생하는지 확인하십시오.
  8. 경고 마커 소유권은 위치 기반이며, 정규식 체인이 아닙니다(Check 22). 위키는 [[Paper]]⚠와 ⚠[[Paper]]를 모두 사용할 수 있습니다. 글리프의 소유자는 왼쪽으로 트리밍된 텍스트가 ]]로 끝나는 경우 바로 왼쪽의 링크이고, 그렇지 않으면 오른쪽의 링크입니다. 인접한 링크가 없는 글리프는 일반 텍스트 주의사항입니다. 두 개의 연결된 정규식으로 이를 해결하지 마십시오(두 번째 정규식이 이웃 링크의 마커를 먹어버리고 검증되지 않은 소스의 플래그를 조용히 제거합니다). 마커의 대량 편집은 변경 전후에 인용별 인구 조사가 필요합니다.

검사 작동 방식

#이름플래그 대상예외
1고립 개념어떤 논문/책에서도 역링크가 없음(인라인 링크 또는 concepts_touched) AND 형제 개념에서도 없음(인라인 또는 related_concepts); 형제 항목은 합성 허브가 오탐하는 것을 방지스텁
2고립 방법논문/책에서 역링크가 없음 AND 논문/책으로의 링크가 없음스텁
3빈 concepts_touched필드가 null, 비어있거나 []인 논문 노트 (일괄 수집 시 프론트매터 손상의 지표)스텁
4출처 없는 주장최소 unsourced_threshold개 라인에 주장 동사(verb_list)가 포함되어 있고, 위키링크가 +/-unsourced_radius 라인 내에 없거나 위키링크된 제목 아래에 없는 개념 노트스텁
5깨진/플레이스홀더 위키링크전체 볼트 인덱스에 없는 대상(broken), 또는 확인되지 않을 때 placeholder_wikilink_patterns와 일치(placeholder), 또는 비어 있음([[]], empty-target)link_target_ignore_patterns (Bases 임베드)
6드래프트promote: 최소 min_distinct_sources_for_final개의 고유한 소스 작업을 인용하는 드래프트(책과 해당 장은 하나의 작업). stale: 기준 미만이거나 날짜가 없는 stale_days보다 오래된 드래프트없음
7인덱스 커버리지베이스명이 index.md에서 위키링크가 아닌 노트스텁; index_mode가 bases인 경우 건너뜀
7b인덱스 섹션 잘못 배치잘못된 ## 섹션 아래의 - [[X]] (index_sections)bases 모드에서 건너뜀
8책 chapters_ingested 동기화선언된 세트가 디스크의 {book}_ChNN.md 파일과 다름스텁 장
9book: 없는 장book: 링크가 없거나 확인되지 않는 *_ChNN 노트없음
10빠른 통계 이탈## Quick Stats에 선언된 개수가 매핑된 폴더의 실제 파일 개수와 다름 (quick_stats_labels)없음
11필드별 커버리지 이탈## Coverage by Field의 개념/방법 열이 실제 비스텁 개수와 다름(필드 행은 field: 기준, -> 하위필드 행은 [[MOC_*]] 링크를 기준으로 subfield: 기준; 하위필드에 노트가 있지만 행이 없으면 MISSING-ROW)스텁; 필드 없는 노트는 INFO
12양방향 concepts_touchedpaper -> concepts_touched[token]에서 대상이 [[paper]] 역링크가 없음(asymmetry, 자동 수정 가능) 또는 노트로 확인되지 않음(missing_target, 토큰 트라이징)없음
13링크 없는 별칭다른 개념/방법의 본문에서 표준 노트로 링크 없이 사용된 문서화된 별칭(독특한 약어 또는 다중 단어 구문). INFO스텁; alias_link_stoplist; 인용구는 검색되지 않음
14언어 레이더위키 언어가 아닌 언어의 제목(H2-H6) 또는 본문에서 최소 prose_threshold개의 중지 단어 적중. 보고 전용; language_radar.enabled가 아닌 경우 비활성화됨스텁
15합성 레이더final 개념/방법 중: missing = 지식 상태 블록 자격이 있지만 없음; stale = 블록이 인용된 작업의 가장 최근 last_verified보다 오래됨비최종
16상태 어휘status가 status_by_type[type]에 없음, status 또는 type 누락, 또는 템플릿 누수(`draftfinal`)
17source_verification 없음씰이 없는 논문; abstract로 시작하는 값은 씰이 아님. INFO 백로그스텁
18확인되었지만 불완전volume 또는 pages가 없고 날짜가 있는 check18_exempt: "YYYY-MM-DD, reason"가 없는 씰이 있는 논문; 학술회의 논문 및 논문은 장소와 형태로 예외스텁
19evidence_level 어휘 외evidence_level_vocab에 없는 값 (논문만 해당)없음
20유용한 인용구 ]]## Useful Quotes 아래의 인용구에 누출된 ]]없음
21전문 이전 코호트synthesis.prefulltext_cutoff 이전 날짜의 논문으로 전문 수준 씰이 없음. INFO스텁
22오래된 전문 이전 마커이미 전문 씰이 있는 논문을 소유한 위키링크에 대한 ⚠, 세 가지 꼬리 예외(본문 주의사항, 날짜가 있는 이탤릭 주석, (N src 신뢰도) 후. 실제 거짓 양성이 있음없음
23채워지지 않은 주장 플레이스홀더unfilled_claim_patterns와 일치하는 라인(출처는 명명되었지만 주장이 작성되지 않음)없음
24사용 중단된 프론트매터 키deprecated_frontmatter_keys에 있는 키 (기본값 journal에서 venue로); 정확히 일치하므로 거짓 양성 없음없음
25인용되지 않은 그림위키링크가 반경 내에 없는 통계 수치(numeric_claim_patterns), cited / block / methods / domain으로 분류. INFO. 아무것도 예외되지 않음스텁; 인용구 건너뜀
26표 열 불일치행의 셀 수가 구분자 행과 다른 표 (유일한 구조적 검사)없음
27모지바케(Mojibake)encode('cp1252').decode('utf-8') 왕복 시 다른 문자열이 되는 라인없음
28last_verified 없는 씰source_verification이 있지만 last_verified가 없는 논문/책 (Check 15 stale에 보이지 않음). INFO없음
29볼트 외부 슬러그 링크memory_slug_prefixes의 슬러그에 대한 위키링크, 볼트 전체. 목록이 비어 있지 않은 경우에만 활성화memory_slug_exempt_files
30어휘 동기화_VOCABULARY.md가 활성 개념/방법을 누락(missing)하거나 사라진 노트의 행을 보유(ghost). INFO; 해결책 /vocabulary-update없음
31텍스트 없는 씰최대 60자이고 어떤 채널에도 설명 텍스트가 없는 씰. INFO없음
32씰 없는 쌍(노트, 지식 상태 블록에서 인용된 작업) 쌍으로 소스 노트 씰이 노트를 명명하지 않음. 차단; seal_debt_file에 선언된 부채는 보고되지만 계산되지 않음선언된 부채
33제목 또는 학회지 없음title 또는 venue가 비어 있는 논문스텁

호출

볼트(위쪽으로 가장 가까운 wiki.config.json이 설정)에서:

python skills/wiki-lint/scripts/lint.py                 # 모든 검사; 목록은 _temp/에
python skills/wiki-lint/scripts/lint.py --only 5,12     # 선택된 검사
python skills/wiki-lint/scripts/lint.py --self-test     # 픽스처와 expected_counters.txt 비교
python skills/wiki-lint/scripts/fix.py check12 --dry-run
python skills/wiki-lint/scripts/fix.py promote _temp/promote_batch.txt
python skills/wiki-lint/scripts/fix.py index            # index_mode "manual" 및 이전 lint 실행 필요

플래그, 설정 키 및 각 검사가 작성하는 파일: references/cli-reference.md.

무엇을 언제 편집할지

  • 새 위키 폴더 (예: datasets/): wiki.config.json의 folders에 추가하십시오. 노트가 생성되기 전에 등록되어야 합니다. 그렇지 않으면 모든 링크가 깨진 것으로 읽힙니다.
  • 새 상태 값: lint.status_by_type.{type}에 추가하십시오. 새 노트 유형: 허용 상태와 함께 유형을 추가하십시오.
  • 개념/방법의 새 필드: field_titlecase_map에 슬러그를 추가하십시오.
  • Check 4 개선: lint.verb_list. 허용 범위 완화/강화: lint.defaults.unsourced_radius.
  • 새 플레이스홀더 패턴: lint.placeholder_wikilink_patterns (확인되지 않는 대상에만 적용됨을 기억하십시오).
  • 검사가 스텁을 건너뛰어야 함: lint.stub_exempt_checks에 번호를 추가하십시오.
  • 언어 레이더 활성화: examples/languages/es.json을 복사하거나 (또는 직접 목록을 작성하여) lint.language_radar에 넣으십시오.
  • 새 검사 추가: wikikit/lint/checks_*.py에 구현하고, 카운터를 expected_counters.txt에 추가하고, 검사를 실행하는 픽스처를 추가하며, references/check-origins.md에 항목을 작성하십시오. 동기가 문서화되지 않은 검사는 처음으로 잡음처럼 보일 때 비활성화됩니다. 동기를 찾을 수 없으면 "not documented"라고 작성하십시오. 절대 임의로 만들지 마십시오.

안전 규칙

  • 린트는 위키에 대해 읽기 전용입니다. --out-dir(기본값 _temp/)에 검사별 목록만 씁니다.
  • fix.py는 보고된 부분(역링크, 상태)에서만 노트를 변경하고, 각 파일의 줄 끝을 유지하며, 모든 변경 사항을 롤백을 위해 로깅합니다.
  • 휴리스틱 변경이 올바른지 확실하지 않으면 먼저 픽스처를 작성하고, 자체 테스트가 실패하는지 확인한 후 변경하십시오.
  • 캐시 디렉터리는 절대 버전 관리되지 않습니다 (_temp/ 및 기타는 .gitignore에 유지). 버전 관리된 측정은 오늘의 것처럼 몇 달 후에 읽힙니다.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

관련 스킬