ライブラリ構築
プロジェクト向けにZoteroコレクションに出典を追加します。捏造出典に対する二重防御:(1) 追加前にすべての候補を実際の出典に対して検証、(2) 追加後に同梱の決定論的チェッカーを実行 — 未検証のアイテムは送信されません。グローバル権限ルール(引用の捏造禁止、不確実性の報告)は常に適用されます。
0. ステップ0 — 他のすべての作業の前にライブラリ全体を読む
スコープ設定、検索、最初の候補提案の前に、対象ライブラリをダンプしてすべて読んでください:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/build-library/library_inventory.py --group <ID> # または --user
python3 ${CLAUDE_PLUGIN_ROOT}/skills/build-library/library_inventory.py --group <ID> --grep <用語>
トップレベルアイテムごとに1行:年、PDFの有無、著者、タイトル、出版物、アイテムキー。100アイテムのライブラリは3kトークン未満です。これをスキップする予算的理由はなく、代替もありません。大規模ライブラリ(数千アイテム)の場合は、完全ダンプをファイルに保存し、関連する --grep スライスと全体像を読み取ってください — ただし、コーディネーターは依然としてチェックを担当し、grepされなかったスライスは「不在」の証拠にはなりません。
これは重複排除スクリーンの一部ではなくステップ0です。なぜなら、ライブラリを知ることで何を探すべきかが変わるからです。これをスキップした実行では、ユーザーが既に所有しているものを提案し、「新たに特定した」と説明し、コレクションのギャップについて誤った主張をすることになります。
4つの厳格なルール、それぞれ実際の障害から(2026-08-01、105アイテムのグループライブラリで発生):
- 在庫確認や重複チェックをサブエージェントに委任してはなりません。 ある研究サブエージェントは、グループが「リストされた13アイテムと無関係な作品数点のみ」を保持していると報告しました。実際は105アイテムでした。コーディネーターはそれを信じて3つの重複を作成しました。サブエージェントは候補の発見には適していますが、コーディネーターがライブラリの把握を担当します。
- サブエージェントの否定的な発見は未検証として扱います。 「確認したが存在しない」は、まさにサブエージェントが誤る主張です。なぜなら、不在は狭い検索範囲内では反証不可能だからです。「ライブラリにない」という主張は、自身の在庫確認と照らし合わせて再確認してください。
- すべての追加はチェックを通過します。遅れて追加されるものも含みます。 3つの重複のうち2つは、セッションの最後に追加されました。直前に読んだ記事の脚注に基づいて、メインパイプラインの外で追加されたため、スクリーンを完全にすり抜けました。どんなに小さく、どんなに遅い候補でもチェックを怠ってはいけません。既に取得した在庫をgrepしてください。
- 在庫情報を引き継ぎます。 出典を探すように依頼されたサブエージェントには、実際のリスト(またはフィルタリングされたスライス)をプロンプトに貼り付けて渡してください — 自分で確認しに行くように指示してはなりません。
ライブラリ自体も証拠です。 「何が不足しているか」というタスクの場合、ユーザーが既に所有しているものは、彼らが何に関心を持っているかを示し、多くの場合、回答を再構成します。このルールを引き起こした実行では、ユーザーのライブラリには、メモがまさに未着手と説明したトピックに関する刑事法の深い文献棚が含まれていることが判明しました — これにより、所見は「誰もこれについて書いていない」から「この2つの文献は互いに引用していない」に変わりました。在庫がプロジェクトについて何を語っているかを読み取ってください。単なる重複マッチングのためだけでなく。
1. Zotero配管
zotero / zotero-group MCPツールは読み取り専用です(重複チェックと検索に適しています)。すべての書き込みは、Zotero Web API v3を介して、~/.claude.json の zotero エントリのキー(env.ZOTERO_API_KEY;個人ライブラリ、<USER_ID>、および使用するグループライブラリへの書き込みアクセスが確認済み)を使用して行われます。
- コレクション:
GET /users/<USER_ID>/collections?limit=100→ ターゲットキーを見つける;ユーザーが新しいコレクションを希望する場合はPOST /collectionsで作成(最初に名前を確認)。 - 重複チェック — まず在庫確認(§0)、次に候補リストをスクリーニング(§2a)、追加前にバックストップ:最初にライブラリ全体を読み(§0)、検証やPDF作業の前に候補リストの重複を排除し(§2a)、その後、
POST /itemsの直前に軽量な最終チェックをバックストップとして保持 — これにより、同じ実行で以前に追加されたアイテムや、以前のスクリーンで見逃された正確な版の衝突をキャッチします。実行途中での一回限りのルックアップには、library_inventory.py --grep <用語>がmcp__zotero__zotero_search_itemsよりも優れています。なぜなら、新たな狭いクエリを発行するのではなく、既に保持しているリストを検索するからです。 - アイテム作成:JSON配列を使用して
POST /users/<USER_ID>/items(1リクエストあたり≤50)。レスポンスのsuccess/failedマップを確認してください。フィールドが不明な場合は、GET https://api.zotero.org/items/new?itemType=bookから空白のテンプレートを取得します。 - 慣例:イラストレーター/「with」クレジット →
contributorクリエイターに加えてextraノート(Zoteroの書籍にはイラストレーター役割がありません);編集者 →editor;版元の実際の出版社/インプリント(例:「Sentinel」、ただし「Penguin」ではない);確認済みの場合は完全な出版日、そうでなければ年;書籍には常にISBN、記事には常にDOI。
1a. 法律評論記事メタデータ — Zotero Connectorの欠陥に対する修正(著者、2026-07-16)
ClaudeはWeb APIを介してアイテムを作成するため、ユーザーのZotero Connectorが確実に誤る項目を正しく設定できます。追加されるすべての法律評論記事に適用されます。Hein(§4a)は正しいデータを示すため、フィールドはそこから取得してください。
- 先頭の「The」/「A」/「An」: 記事を自然な先頭位置に保持 — タイトルは
The Common Lawとし、Connectorのソート反転表記Common Law, Theにしないでください。 - 年 = 発行号の年であり、巻の期間ではありません。 Connectorはしばしば巻全体の日付範囲を取得します。特定の号の年を使用してください。これはHeinの引用で示されています。
- 末尾の疑問符: 保持してください —
Are Judges Political?とし、Are Judges Politicalにしないでください。 - タイトル内のイタリック体: ZoteroのタイトルフィールドはインラインHTMLを受け入れます — 判例名(およびその他のBluebookでイタリック体にされる用語)を
<i>…</i>で囲みます。例:The Real Meaning of <i>Erie</i>またはRethinking <i>Chevron</i> Deference。Zoteroはこれらをイタリック体としてレンダリングおよびエクスポートします(これはユーザーが手動で追加していた<i>判例名</i>です)。 - タイトルから付加された記事種別/シンポジウムラベルを削除 — ただし、実際のBluebook指定は
extraに保持。 Connectorは指定をタイトルに付加します —Essay、Comment、Note、Foreword、Book Review、Symposium: <名前>など。記事の実際のタイトルだけを、それが作品の先頭/Bluebook引用に表示されるまま保持してください。末尾のテキストが本当のサブタイトルか付加ラベルか不明な場合は、最初のページを確認してください。- 学生ノートとコメント(およびBluebookが著者とタイトルの間に印刷するその他の指定 —
Recent Development、Essay、Foreword、Book Reviewなど):ラベルを単に破棄しないでください。アイテムのextraフィールドにgenre:行として記録します — 学生ノートの場合はgenre: Note、コメントの場合はgenre: Comment(タイトルケース;スタイルは関係なくタイトルケースにしますが、クリーンに保存してください)。Bluebookスタイルはそれを適切な場所に挿入します(Jane Doe, Note, <i>Title</i>, 120 Harv. L. Rev. 1627 (2007))。上記のようにタイトルからラベルを削除かつgenre:行を追加 — これらの作品ではこの2つはセットで行われます。 - 匿名の学生ノート(著者なし):クリエイターを空のままにし、それでも
genre: Noteを設定します。extraフィールドが既に他の行を保持している場合(例:Verified-URL:)、新しい行にgenre: Noteを追加してください — 上書きしないでください。
- 学生ノートとコメント(およびBluebookが著者とタイトルの間に印刷するその他の指定 —
- サフィックス(「Jr.」、「III」、「Sr.」): Zoteroにはサフィックスフィールドがありません — サフィックスを名フィールドにエンコードし、カンマとスペースなしで名前の後に追加します(姓は姓のままにします;サフィックスを姓に追加したり、2人目の著者を追加したりしないでください)。サフィックスの先頭の
!は、その前にカンマを表示するかどうかを制御します(citeproc-jsマークアップ、著者による):- 「John Smith Jr.」(カンマなし)→
firstName: "John,Jr."、lastName: "Smith" - 「John Smith, Jr.」(カンマあり)→
firstName: "John,!Jr."、lastName: "Smith"名前にはミドルネーム/イニシャルを含め、カンマの前に置きます(例:John B.,Jr.)。数字/その他のサフィックスも同様のメカニズム —John,IIIvsJohn,!III、John,Sr.など。著者/ソースが使用するカンマ形式に合わせてください。
- 「John Smith Jr.」(カンマなし)→
- 雑誌略称(Bluebook、混成文字ケース): 常にZoteroの
journalAbbreviationフィールド(UIでは「Journal Abbr」)に、雑誌のBluebook略称(表T13)を通常の混成文字ケースで設定してください —Colum. L. Rev.、Harv. L. Rev.、Nw. U. L. Rev.、J. Sup. Ct. Hist.、Sup. Ct. Rev.— すべて大文字ではありません。引用スタイルがスモールキャップス自体を適用するため、Colum. L. Rev.を保存し、COLUM. L. REV.は保存しないでください。完全名はpublicationTitleに残ります;略称はjournalAbbreviationに入ります。Heinの引用表示は大文字/スモールキャップスでレンダリングします(「62 COLUM. L. REV. 633」) — この表記を使用しますが、混成文字ケースに変換してください;馴染みのない雑誌の場合は、推測するのではなくT13形式を確認してください。オンラインコンパニオン/サプリメントの場合は、ブルーブックに従ってサプリメント名を省略して追加します —Forum→F.(例:Harv. L. Rev. F.)、一方Colloquyには短縮形がありません(Nw. U. L. Rev. Colloquy)。既知の名前固有の例外(これらを「修正」しないでください):California Law Review→Calif. L. Rev.(Cal.ではない。カリフォルニアはレポーターなどではCal.ですが)。このCalif.の異形はその雑誌に固有です — 対照的にSouthern California Law Review→S. Cal. L. Rev.では、カリフォルニアは通常のCal.を取ります。
2. 候補を見つける
リクエストが自由形式の場合は、ユーザーとスコープを協議してください(どの判事/学者/時代か;書籍のみか記事もか;一般書かケースブック/論文か — 判断を要する点は、黙って決めるのではなく、レポートにフラグを立ててください)。これは§0の後、決して前に行ってはいけません — 在庫はユーザーが既に持っているものを示し、それが何を探す価値があるかを変えます。
並行して検索:WebSearch;Open Library(search.json?title=&author= が bare q= よりも優れています);Wikipediaインフォボックス(/w/index.php?title=<ページ>&action=raw、インフォボックスをgrep)で著名な書籍の出版社/日付/ISBNを取得;出版社ページ。法律学術文献については、HeinOnline(§4)。Google Books APIは共有の匿名クォータであり、多くの場合使い果たされています — ボーナスとして扱い、バックボーンとしては扱わないでください。
2a. 候補をライブラリに対してスクリーニングする
在庫情報を手に、コストのかかる検証→ダウンロード→追加パイプライン(§3+)の前に、候補リストの重複を排除してください。メタデータの検証とPDFの取得(Hein curlチェーン、attach_pdf.py)は実行のコストがかかる部分です。それを既にライブラリにある出典に対して行うのは完全な無駄です。
- 各候補を在庫と照合し、最初に著者+年、次にタイトルで照合します — タイトルは異なります(サブタイトル、「Part I」、ソート反転冠詞、HTMLエンティティ)が、著者プラス年の衝突は、より詳細な確認のための信頼性の高いトリガーです。
- 明確な一致(同じ作品が既に存在する)を削除 — それらを検証したりダウンロードしたりしないでください。
- あいまいなニアミス(同じ著者、類似するが同一でないタイトル;異なる版/刷り;記事とそのオンラインコンパニオン)は、黙って削除せずにフラグを立ててください。正確な版は検証中にしか特定できない場合があるため、本当の可能性のあるものを先に進め、推測して片付けずにレポートに記録してください。
生き残ったものだけが§3を通過します。§1の追加前バックストップが、実行内の重複と正確な版の衝突をキャッチします。
もし重複を作成してしまった場合は、削除する前にマージしてください。 既存のアイテムには、ユーザーのPDF、注釈、タグ、コレクションメンバーシップが含まれている可能性があります。あなたの新しいアイテムには、より良いメタデータが含まれている可能性があります。既存のアイテムに良いフィールドをPATCHし、その後あなたのアイテムをDELETEしてください。古いレコードを決して削除しないでください。(2026-08-01のクリーンアップでは、これにより実際の欠陥が回復されました:ユーザーのKahanアイテムの issue フィールドに文字列「10.2307」があり、DOIがありませんでした。)
ワークフロールール(著者、2026-07-16):すべての法律評論出典をHeinOnline経由で解決してください。 Heinはクリーンで自律的なパスです(§4a:IP認証、ボット壁なし、ゲートなし)。Heinが保有しておらず、オープンリポジトリも提供しない出典は、検証されたレコードなしで追加するのではなく、そのように報告されます(§5)。
3. 検証 → 追加 → 決定論的チェック(譲れない)
追加前:書き込むすべてのフィールドは、取得したソース — Open Libraryのエディションレコード(/isbn/<isbn>.json)、出版社ページ、Wikipediaインフォボックス、書籍販売業者のリスト — からのものでなければなりません。記憶からもっともらしいISBN/日付/出版社を決して書かないでください。破損したOLエディションレコードに注意してください(ISBNの背後に間違った本があることがあります);驚きがある場合は、2番目のソースとクロスチェックしてください。
追加後、同梱のチェッカーを、Zoteroに実際に追加されたものに対して実行してください:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/build-library/check_source.py --collection <KEY> # コレクション全体
python3 ${CLAUDE_PLUGIN_ROOT}/skills/build-library/check_source.py --keys K1,K2,K3 # 新しいアイテムのみ
各アイテムのISBNを5つの独立したカタログ(Open Libraryエディション+検索インデックス、Google Books、Harvard Library、Library of Congress)またはDOIをCrossrefを通じて解決し、タイトル/著者/年の正規化された文字列比較を行います。判定:PASS、FAIL(解決されたが不一致)、UNRESOLVED(識別子がチェックされたどのカタログにも見つからない — 再検証を促すものであり、捏造の証明ではない:カタログは不完全であり、時々ダウンすることがあります)、BAD_ISBN(チェックサム)、NO_IDENTIFIER。--stdin は、追加前に候補を事前チェックするためのZotero形式のアイテムのJSON配列を受け入れます。
追加したすべてのアイテムは PASS で終了しなければなりません。 PASS以外の場合の対処法:
- 1つのソースのみで
FAIL→ 通常はカタログの破損;チェッカーは既に他のソースを試しているため、持続的なFAILは通常、あなたのデータが間違っていることを意味します — 開いている信頼できるページに対して再検証し、アイテムをPATCHしてください(If-Unmodified-Since-Version: <アイテムバージョン>を送信)。開いたページがあなたのデータを確認した場合は、Verified-URL:として記録し、カタログに合わせて正しいメタデータを「修正」するのではなく、そのようにレポートに記載してください。 UNRESOLVED/カタログには新しすぎる(出版から約1年未満の書籍) → フェッチ可能な信頼できるページをVerified-URL:として追加し、CHECKER_INCONCLUSIVEというタグを付けて、それが期待されるカタログ待ち状態であることを示します。NO_IDENTIFIER→ これはバグです。あなたは常にISBNまたはDOIで追加するため。パイプラインを修正してください。BAD_ISBN→ あなたのISBNが不正です。修正されたソースから正しいものを取得するか、代替の識別子(OCLC番号、DOI)を見つけ、アイテムをPATCHしてください。- 複数のソースで
FAIL、またはどんなソースでも解決できない場合は、決してPASSとしてマークしないでください。
決定的チェッカーは、Claudeが何かをでっち上げるのを防ぐフールプルーフです。 Zoteroに書き込むコマンドを発行するたびに、実行することに慣れてください。
4. 法律学術文献 — HeinOnline
HeinOnlineのIP認証コンテンツは、すべての法律評論/ジャーナル記事にとっての基本ルートです。law-bot サブエージェントは特にこれを処理するために作られています。
ワークフロー:
- コーディネーターが
.claude.jsonからHeinセッションを初期化し、以下のようにサブエージェントに渡します:law-botサブエージェントは、HeinOnlineで記事を検索し、書誌情報を取得し、PDFをダウンロードします。すべての検証は、HeinOnlineのメタデータが信頼できるソースであることに基づいて行われます。 - サブエージェントは、特定された記事のリストを返します。
- コーディネーターは、§2aの重複チェックと§3の検証を実行します。
HeinOnline初期化(コーディネーターによる):
python3 ${CLAUDE_PLUGIN_ROOT}/skills/build-library/hein_session.py init --group <グループID>
これにより、~/.claude.json の cookie セクションにHeinOnlineセッションクッキーが設定されます。(注意:HeinOnlineは、機関プロキシを介したIP認証を必要とします。このスクリプトは、env に設定されたプロキシURLを使用します。)
サブエージェントのスコープ: law-bot は、法律評論記事の特定、検証、PDFダウンロードを処理します。以下のコマンドを使用します:
heinonline_search— 検索クエリに基づいて記事を見つけるheinonline_get_metadata— 特定の記事の書誌情報を取得するheinonline_download_pdf— PDFをダウンロードする
5. レポート
すべての実行は、確認が必要なものがない限り、以下の内容を含む簡潔なレポートで終了します。
- 追加されたアイテム(タイトル、著者、年、識別子)
- 重複としてスキップされたもの
- 検証できずに保留された出典
- あいまいなニアミスに関する注記
- チェッカーの結果(すべてPASSである必要があります)
アイテムが FAIL または UNRESOLVED で終了した場合、レポートにはその事実、その理由、およびそれに対して何が行われたか(再検証、PATCH、または展開できない Verified-URL)を明確に記載する必要があります。
6. スキルのバンドル
このスキルには、build_library ディレクトリに以下のスクリプトが含まれています:
library_inventory.py— Zoteroライブラリの内容をダンプするcheck_source.py— 追加されたソースに対して決定論的チェックを実行するhein_session.py— HeinOnlineセッションを管理するattach_pdf.py— ローカルPDFをZoteroアイテムに添付する
7. 制限事項
- このスキルは、機関プロキシを介したHeinOnlineへのアクセス権があることを前提としています。
- Google Books APIのレート制限は、ライブラリ構築中に発生する可能性があります。
- Open Libraryのレコードが破損している場合があります。スキルは、複数のソースとクロスチェックすることでこれを軽減します。
- 大量のアイテム(>50)を追加する場合は、Zotero APIのレート制限を尊重するためにバッチ処理が必要です。