公開されているClaude Code用の図解スキルを、クローンせずにデューデリジェンスした

開発claude-code-tools

公開されているClaude Code用の図解スキルを、クローンせずにデューデリジェンスした

GitHub で図解の型を27種類そろえたリポジトリを見つけた。

cathrynlavery/diagram-design は Claude Code 用のスキルとして配られていて、今使っている svg-diagram に取り込める部分があるはずだと思った。 目当ては27の型を選べるところで、中身もおそらく SVG だろうと踏んだ。

ただし、そのまま持ち込む気にはならなかった。 他人の書いたスキルは、Claude に読ませた時点でそのまま指示になる。 そこで「いきなり git clone するな。実態をまず見て安全性を確認しろ。変なプロンプトが仕込まれている可能性もある」と条件を付けて、デューデリジェンスから始めさせた。

クローンせず、隔離した場所で中身だけ見る

GitHub API でファイル一覧を取り、固定 SHA のアーカイブを scratchpad へ展開させた。 プロジェクトの外に置いて、実行はしない。読むだけ。

出てきた実態はこうだった。

  • 実行されうるコードは Python 3本のみ。いずれも作者のメンテナンス用で、スキルとして読むだけなら1行も走らない
  • 外部通信はアイコン取得スクリプトの urllib だけ。取得先は既知の OSS リポジトリ
  • 同梱されている89本の HTML と86本の SVG に、<script> もイベント属性も外部参照もゼロ

そのうえで、プロンプトインジェクションの隠蔽に使われる手口を228ファイルぶん機械的に洗わせた。 ゼロ幅文字、BiDi 上書き文字、Unicode タグ文字、私用領域、巨大な base64、コメント内の命令形。

コメント内の命令形だけが8件ヒットした。 中身を開いたら、全部が図の部品名の注記だった。作例の図が「Claude Code でスキルを書くべきか判断する流れ」を題材にしていたため、検索語に引っかかっただけだった。

途中、検査スクリプトが cp932 で落ちた。 Windows のコンソールが Unicode を吐けずに死ぬ、いつものやつだ。文字コードを指定して回し直させた。

悪意ある文字を探すだけでは、検査項目が足りていなかった

ここまでの検査で見ていたのは、実行コードと JavaScript と不可視文字である。 ところが、スキルでは Markdown の普通の文章そのものが実行指示になる。悪い文字を1つも含まないまま、危険な挙動を書かせることができる。

そこで全リファレンスを、ネットワーク、読み取り、書き込み、プロセス起動、承認ゲートの有無という観点で読み直させた。

該当は2本。どちらも正当な機能だが、丸ごと導入するなら挙動を許容するかどうかの判断が要る。

  • オンボーディング用のリファレンスは、インストール済みの他のスキルのディレクトリを glob して中身を全部読む動線を持っていた。書き込みの前には差分提示と承認が3箇所に明記されている一方で、読み取り側のゲートは緩い
  • エクスポート用のリファレンスは Playwright を起動して PNG 化するが、「未導入なら手順を示して停止し、自動インストールはするな」「エクスポートは手動のみ」と明記されている

作者は権限の扱いに慎重だと読めた。 とはいえ ~/.claude/skills/ には業務ルールが入っている。丸ごと導入するなら、他スキルを読みに行く動線ができることを承知したうえで決めることになる。

この時点で、取り込み方の方針が固まった。プラグインとして有効化するのではなく、必要な記述だけを手で書き写す。それなら動線は生まれない。

目当てだった27の型は、思ったほど厚くなかった

型の数は確かに27だった。リポジトリの説明文はいまだに13型のままだが、これは v1 時代の記述で、プラグイン定義も実ファイルも27で揃っている。

ただし厚みが偏っていた。 19〜30KB ある7本はすべてデータ基盤系で、データレイクや ETL や権限設計といった作者の実務領域とみられる。 一方、フローチャートや ER 図や状態遷移といった汎用の型は1〜3KB しかない。レイアウト規約が3行、アンチパターンが3行、作例へのリンク。それだけ。

つまり「27型ぶんの図解ノウハウが手に入る」わけではなかった。 濃い知見が入っているのは、日本語記事ではまず使わない領域のほうだった。

代わりに、期待していなかったところに使えるものがあった。型の下に敷かれた規律である。

  • コネクタの5原則。ラベルの背後に置く不透明マスクは線に接触させない。同じ経路に2本を走らせない。端点でないボックスの背後を通さない
  • 複雑度の上限表。ノードは最大9、矢印は最大12、強調色は最大2。超えたら概要図と詳細図に分割する
  • 色とフォントの逸脱を検出する lint。既存の lint はテキストのはみ出しと折り返ししか見ておらず、パレット外の色は目視頼りだった

既存スキルは「1図1メッセージ」という質の規律は持っているが、量の上限を数値で決めていない。 図が崩れる事故のうち、ラベルが線を隠す、線が重なる、線がボックスの裏を通るの3つは、毎回 Chrome で目視して人力で見つけていた。描く前に禁じられるなら、そのほうが早い。

既存の規定とぶつかる原則が1つあった

コネクタの原則のうち、「同じ辺に複数つなぐときは接続点を扇状に散らし、共有しない」という1本だけが、既存スキルの §7.2 と真正面からぶつかった。

既存は逆を勧めている。 1つのボックスから上下に分岐するとき、共通の縦線でいったん合流させる T字結合だ。実装例まで載っているし、これまでに描いた図もそれで描かれている。

そのまま足すと、スキルの中に矛盾した必須命令が2つ並ぶ。次に図を描くとき、どちらに従えばいいのか決められなくなる。

この矛盾は、Codex にレビューさせて初めて出てきた。P0 が3件返ってきた。 そのうち「プラグイン定義は13型のままだ」という指摘は、raw.githubusercontent.com から取り直したら27型と書いてあり、Codex の誤りだった。 残りは正当で、なかでも §7.2 との矛盾は完全な見落としだった。報告書の中核に関わる箇所だったので、そこだけ書き直させた。

裁き方は2つある。T字結合を明示的な例外として残すか、§7.2 を廃止して一本化するか。後者を選ぶと、過去に描いた SVG を描き直すことになる。

取り込まないと決めたもの

見た目のレイヤーは、丸ごと合わなかった。

先方既存判断
鉄錆とコーラルのアクセントグレー8段階+印刷マゼンタ既存を維持
Geist / Instrument SerifNoto Sans JPGeist に日本語グリフが無い
8px を常用11以下は使わない日本語は8pxでは読めない
自己完結 HTML にインライン SVG.svg 単体ファイルを <img> で参照既存は Nuxt Content で崩れた実績があっての規定

最後の納品形式が一番危ない。作例の HTML をそのまま流用すると、既存サイトでは表示が壊れる。

ついでに、リポジトリが謳う「自己完結」は厳密には嘘だった。 テンプレートが Google Fonts を <link> で外から読んでいる。既存は日本語書体を使うので、そもそもこの指定を採用しない。実害は無い。

ライセンスの整理は、一度出した結論を引っ込めた

最初は「自分の言葉で書き直すなら出典の注記だけでよい」と整理させていた。 これは撤回した。

今回足そうとしているのは、40〜60行におよぶ規則群と数値と配置の計算式である。翻訳や翻案は派生物とみなされうるし、分量としても MIT のいう「実質的な部分」に当たると読む余地がある。 ライセンス全文と著作権表示を置く場所を新設し、どの節が由来かを明示する形に変えた。

決裁フォームまで作って、明日に回した

判断が要る項目は4つになった。コネクタ規律の裁き方、複雑度の上限表を入れるか、色の lint を作るか、27型の選定表をどう扱うか。 それぞれ3択にして、推奨を1つ立てた決裁フォームを作らせた。あわせて図を1枚描かせ、SVG の機械検証は errors 0 / warnings 0 で通った。HTML を生成して Chrome で開かせた。

一度「決裁ボタンが描画されていない」と報告が上がってきたが、検証に使ったセレクタが違っていただけで、実際は4問とも3択と自由記述欄と推奨バッジ付きで出ていた。

そこで止めた。 これも明日やりたい、と決めて、積み残しとして /add-task で登録させた。決裁フォームは未回答のまま、サーバーは落として明日また立て直す。

登録のときにバックスラッシュのエスケープでスクリプトが壊れ、書き直してファイルから実行した。表示が化けたのはまた cp932 で、この日2回目だった。

明日やること

  • 決裁フォームを立て直して4問に答える。T字結合をどう裁くかが本丸
  • 決めた方針に沿って、コネクタ規律のうち既存に無い分を日本語で書き足す
  • 複雑度の上限表を、日本語記事の図解に合う数値へ組み替えて追記する
  • lint-svg-text.mjs に、パレット外の色と純黒と許可外フォントの3検査を足す
  • 第三者ライセンスの記載場所を新設し、MIT 全文と著作権表示を置く

調べただけで、まだスキルには1行も足していない。 安全だとは分かったが、取り込む中身は当初の見立てからずれた。型が欲しくて拾ってきたのに、手元に残ったのは線の引き方の規則だった。