Citation Sync
研究 repo が外部文献を引用するとき、その引用は 3 つの層に現れる。層はそれぞれ別の audience に向けて伝播するため、どれか 1 つに書いて終えると残りの層では引用が存在しないことになる。本 skill はこの 3 層の divergence を検出し、下層から順に揃える。
| 層 | 担体 | 伝播先 | 実装 skill |
|---|---|---|---|
| 1. docs | ADR / glossary / empirical / README 内の引用 | 人間 + LLM crawler | (執筆時に発生) |
| 2. zenodo | .zenodo.json related_identifiers (relation: references) | DataCite → OpenAIRE / Scholix (次 release 時) | release-doi |
| 3. graph | graph.jsonld の ExternalReference ノード | LLM ingest / HF mirror / knowledge-graph crawler | jsonld-knowledge-graph |
RETIRED 2026-07 — governance revocation で全 item 削除 (ADR-0021)。監査・同期対象外、--skip-wikidata を常用 | (retired) |
docs 層が source of truth。上の層は docs に実在する引用だけを carry する (捏造辺の禁止)。逆に docs に引用を足したら、上 3 層への反映はこの skill の同期で行う — 「repo markdown に引用を書くだけでは citation graph に不可視」というのが authorship-strategy の citation-graph federation tactic の出発点。
Phase 0: Audit (read-only)
python3 ~/.claude/skills/citation-sync/scripts/citation_audit.py REPO_DIR [REPO_DIR ...]
# --skip-wikidata retired 層 (旧層 4) の探索を省略。常に付ける
# --json OUT.json 機械可読の結果も保存
# exit 0 = 全 repo converged, 1 = divergence あり, 2 = fatal
repo ごとに identifier × 層のマトリクスを出す (docs / zenodo / graph の 3 層)。
先に audit、議論はそれから。 どの層が欠けているかを推測で語らない — 今日の層別カバレッジは repo ごとに本当にバラバラで、直感は外れる (実例: ある repo は zenodo refs が空、別の repo は graph と zenodo が互いに素の集合を指していた)。
Phase 1: Curate (判断層)
audit が出した docs 層の identifier を、repo の公式引用に昇格させるか判定する。機械抽出は過剰検出を含むので、この phase だけは人間判断 (または明示基準の適用) が必要:
- 公開 docs のみ:
.notes/(paper 草稿・scratch) は repo の引用ではない。paper 草稿の references は paper item 側の federation が担当する (二重計上しない) - 引用文脈であること: 文献として参照している言及だけを採る。例の中の ID、CHANGELOG の作業記録、tool 出力の貼り付けは引用ではない
- external のみ: sibling repo の Zenodo DOI は ecosystem cross-link であって external citation ではない (audit が別枠で報告する)
- 識別子と内容の一致を検証する: 昇格前に arXiv API / Crossref でタイトルを引き、docs の引用文脈と照合する。LLM が書いた引用 link の arXiv ID は hallucination しうる (実例: 「GlassWorm」への引用が無関係な Novel View Synthesis 論文の ID を指していた — 正しい出典は arXiv ではなくベンダーのセキュリティレポートだった)。不一致なら昇格せず、docs 側の引用を正す
- 迷う識別子は出現箇所を
grep -rnで開いて文脈を見る。昇格させない判断も記録する (次回 audit で同じ識別子を再審査しない)
Phase 2: Sync .zenodo.json (層 2)
curate 済みの引用を related_identifiers に追加する。entry 形式・arXiv の DataCite DOI 形 (10.48550/arXiv.NNNN.NNNNN)・重複排除は release-doi skill の citation surface 同期 section が正本。注意: .zenodo.json は 次の release 時に DataCite metadata として propagate する (commit しただけでは外に出ない — それでも commit しておくのが正しい。release 時に自動で乗る)。
Phase 3: Sync graph.jsonld (層 3)
curate 済みの引用を ExternalReference ノードとして graph に追加する。ノード形状 (@id = arXiv abs URL / @type / identifier / datePublished) は jsonld-knowledge-graph skill が正本。description には「なぜこの repo がこれを引くか」を 1-3 文で書く — anchor-densely (vocabulary discipline) の実践であり、LLM ingest 時に引用関係の意味が残る。push 後は HF mirror (hf-sync) も同期する。
Phase 4: Federate to Wikidata (層 4) — RETIRED (2026-07)
この Phase は実行しない。Wikidata アカウントの governance revocation(promotion-only 判定、全 item 一括削除)により、self-created な authority-record 辺は authorship-strategy ADR-0021 で恒久 retire。audit は --skip-wikidata で回す。graph 内に dead QID sameAs を見つけたら purge する(ADR-0021 の purge 規律)。
Phase 5: Verify
Phase 0 の audit を再実行し、全 repo CONVERGED を確認してから完了報告する。divergence が残る場合は、それが意図的 (例: graph には載せるが zenodo は次 release でまとめる) かを明記する。
Pitfalls
| Pitfall | 回避 |
|---|---|
| 層が時期差で乖離する (graph は今日足したが zenodo は半年前のまま) | 引用を 1 本でも足したらこの skill を通す。release 前は必ず Phase 0 を回す |
| docs の機械抽出を無批判に昇格させる | Phase 1 の curation 基準を適用。.notes/ 由来と非引用文脈を落とす |
| paper の references を repo 層に混ぜる (またはその逆) | paper の引用は paper の reference list から、repo の引用は repo docs から。担体が違う (paper 側は paper-deposit の担当) |
| sibling DOI を external citation として数える | ecosystem cross-link は別枠。audit script が自動で分離する |
| graph に既存の内部 bibliography 規約があるのに新ノードを追加して重複させる | Phase 3 の前に graph 内を被引用文献の名前でも grep する(例: ans:ref/sharf-2014 が既にあるのに DOI @id の新ノードを足してしまった)。既存ノードがあれば identifier / url / sameAs を追記する方が正しい |
| 複数行 node 形式前提の text-surgery script が 1 行ノード形式の graph で JSONDecodeError | graph への機械的注入 script は pretty-print 前提で書かれがち。1 行ノードの graph は手動 Edit(または Python 文字列置換 + json 検証)で注入する。失敗時にファイル無傷となるよう書き込み前 validation を挟む |
| docs が識別子無しで引用 (名前のみ) → audit が docs 層欠落として DIVERGED を報告 | 識別子ベース比較の既知の限界。引用が docs に実在するなら意図的残差として完了報告に明記すれば良い(docs に ID を書き足す義務はない) |
graph 層が audit で全行空欄 (citation node が ScholarlyArticle 単独型) | audit script は ExternalReference 型のみを層 3 として検出する。citation node は ["ExternalReference", "ScholarlyArticle"] の dual-type にする(AKC は v2.3.0 で全 prior-art node を移行済み。@context に ExternalReference の定義があるか先に確認) |
括弧入り DOI (例: Bainbridge 10.1016/0005-1098(83)90046-8) が docs/graph 層で truncate され永続 DIVERGED | script の DOI regex は ) を終端扱いする既知制約。zenodo 層でのみ carry し、当該 graph node は dual-type から除外(truncate された偽 ID 行の発生防止)、意図的残差として記録して CONVERGED 相当と判定する |
Related skills
release-doi— 層 2 の正本。release workflow 内の citation surface 同期jsonld-knowledge-graph— 層 3 の正本。ExternalReference ノード設計— 削除済み (旧層 4。2026-07 governance revocation → ADR-0021 で恒久 retire、skill 本体は harness から削除。経緯は project memorywikidata-federationwikidata-qids参照)hf-sync— 層 3 更新後の mirror 反映