#!/bin/sh
# Claude Code Skill 설치 스크립트
# 생성: 2026-08-13 · Skill 1개 · 파일 1개
#
#   ./install-skills.sh            ~/.claude/skills/ 에 설치 (모든 프로젝트에서 사용)
#   ./install-skills.sh ./myrepo   ./myrepo/.claude/skills/ 에 설치 (그 저장소 전용)
set -e

DEST="${1:+$1/.claude/skills}"
DEST="${DEST:-$HOME/.claude/skills}"
mkdir -p "$DEST"
echo "설치 위치: $DEST"


mkdir -p "$DEST/biblio-normalize"
cat > "$DEST/biblio-normalize/SKILL.md" <<'SKILL_PAYLOAD_EOF'
---
name: biblio-normalize
description: 병합한 서지 데이터를 정리한다. 빠진 DOI를 OpenAlex·CrossRef로 회수하고, 컬럼별 완성도와 정확도를 분리해 품질 리포트를 낸다. 저널 축약어 처리와 완성도·정확도 구분이 핵심. TRIGGER - "DOI 채우기", "데이터 품질 리포트", "완성도", 수집·병합한 서지 데이터를 분석에 쓸 수 있게 다듬을 때.
---

# 서지 데이터 정규화

## 언제 쓰나

수집·병합이 끝난 뒤. 이 단계를 건너뛰면 **기관 분석과 DOI 기반 연결이 통째로 틀린다.** 두 가지 일이 같은 데이터에 연달아 일어나므로 하나로 묶었다. 기관명 정규화는 `[[institution-resolve]]`.

## 정본 코드

```
~/Documents/혜연/BTC_KOL_PoC/
  fill_doi.py              238줄  빠진 DOI 회수
  quality_report.py        261줄  완성도·정확도 리포트
```

기관명 정규화는 코드가 크고 성격이 달라 `[[institution-resolve]]` 로 분리했다.
두 파일 모두 `--selfcheck` 를 가지고 있다. 규칙을 고치면 먼저 돌린다.

---

## 1. DOI 회수 — 순서가 중요하다

```
① OpenAlex — PMID 로 조인. 식별자 조인이므로 추측이 없다
② CrossRef — 제목으로 검색. 추측이 들어가므로 세 조건을 모두 요구한다
     제목 토큰 75% 겹침 + 저널 일치(축약어 허용) + 연도 ±1
```

**식별자 조인을 먼저 다 돌리고, 남은 것만 제목 검색으로 넘긴다.** 순서를 바꾸면 확실한 건까지 추측으로 채우게 된다.

제목만으로 매칭하면 안 된다. 세 조건을 **모두** 요구해야 오매칭이 안 난다.

### 저널 축약어 — 이걸 빼먹으면 회수율이 6배 틀린다

> `Korean J Gastroenterol` 과 `The Korean Journal of Gastroenterology` 는 같은 저널인데, 토큰을 그대로 비교하면 `gastroenterol` ≠ `gastroenterology` 라서 다른 저널이 된다 — 이걸 빼먹으면 회수율이 60%에서 10%로 잘못 나온다(실측).

`journal_tokens()` 로 토큰화하고 `journal_match(ours, theirs)` 가 축약형을 접두어로 비교한다. 관사(`The`)도 떨군다.

**`--dry-run` 을 먼저 돌린다.** "회수 가능량만 측정"으로 얼마나 채워지는지 보고 나서 실제로 채운다.

---

## 2. 품질 리포트 — 완성도와 정확도를 섞지 마라

> **완성도와 정확도를 섞지 않는다.** 값이 채워졌다(완성도)와 그 값이 맞다(정확도)는 다른 문제이고, 정확도는 독립 근거가 있을 때만 숫자를 낸다. 근거가 없으면 '검증 안 됨'으로 적는다 — **모르는 것을 100%라고 적지 않는다.**

이게 이 스킬에서 가장 중요한 한 줄이다. 컬럼이 100% 채워졌다는 사실은 그 값이 맞다는 뜻이 전혀 아니다.

### 정확도를 주장할 수 있는 근거는 셋뿐이다

| 근거 | 뜻 |
|---|---|
| ① 교차검증 | 서로 다른 두 출처를 대조 (WoS↔OpenAlex, 우리↔OpenAlex) |
| ② 눈가림 실험 | 근거를 숨기고 맞히게 해서 그 근거의 기여를 분리 |
| ③ 정의상 정확 | 원본 식별자를 그대로 옮긴 값 (PMID·DOI·ORCID·연도) |

셋 중 하나도 없으면 그 컬럼의 정확도 칸은 **'검증 안 됨'** 이다. 빈칸으로 두거나 추정치를 적지 않는다.

`filled(db, table, col)` 로 완성도를 세고, `live_evidence(db)` 로 정확도 근거를 모은다. `--md` 로 마크다운을 내서 문서에 바로 붙인다.

---

## 함정

- 이 단계는 **병합 뒤, 분석 앞**에 온다. `[[institution-resolve]]` 와 함께 돌린다.
- DOI 회수는 외부 API를 부르므로 캐시하고 `--dry-run` 을 먼저 돌린다.

## 연관 skill

`[[paper-merge-provenance]]`(앞 단계), `[[paper-source-collect]]`, `[[lit-relevance-classify]]`, `[[excel-case-validator]]`
SKILL_PAYLOAD_EOF

echo ""
echo "완료 — Skill 1개를 설치했습니다."
echo "Claude Code를 다시 시작하면 인식됩니다."
