本文へ移動
公開レビュー中(2026-10-22〜2026-11-21 JST)。参加方法(REVIEW.md) · 進捗の issue

SkillPact · 草案 0.8

SkillPact 0.8 仕様(日本語訳)

要約#

SkillPact は Agent Skills の SKILL.md(変更しない)の隣に置く機械可読の契約 skill.contract.json を定めます。契約には、スキルが何をするか(capabilities)、どんな副作用がありうるか(範囲つきの 6 区分)、何が必要か(requirements)、実行できる適合テスト、ファイルのハッシュと署名を書きます。ツールはスキルをインストールする前に契約を確かめ、ハーネスのポリシーに照らして allow / ask / deny を決め、その結果を各ハーネスの設定に変換できます。

この文書の位置づけ#

  • ドラフト 0.8(2026-10-22)。 SEVENTHWELL(shogo kajiyama)が編集するドラフトです。差分ではなく完全版です。
  • まだ安定版ではありません。0.x の間は版ごとに互換性のない変更がありえます(バージョニング参照)。公開レビューの期間は 2026-10-22 – 2026-11-21(JST)です(REVIEW.md、追跡 issue #1)。「0.8.x 正誤」と記した箇所はレビュー開始後に追加したもので、一覧は CHANGELOG.md にあります。
  • 規範となるのは英語版です。 この日本語訳は参考です。食い違う場合は英語版に従います。
  • ご意見は kajisho5/skillpact の GitHub issue へ。決め方は GOVERNANCE.md にあります。
  • スキーマ:https://kajisho5.github.io/skillpact/schema/v0.8.json、ポリシー:.../schema/policy-v0.8.json(改訂版 policy-v0.8-r1.json〔§13〕、policy-v0.8-r2.json〔§13.3〕)。
  • ライセンス:本文 CC BY 4.0、スキーマと実装 Apache-2.0。
  • 特許:SEVENTHWELL と Shogo Kajiyama は、この仕様の実装に対して、防御的終了つきの無償の特許不主張を誓約しています:IPR.md。
  • メディアタイプ:専用のメディアタイプの IANA 登録は 1.0 の後に検討します(付録 D)。

1. 表記と用語#

「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」は、すべて大文字で書かれた場合に限り BCP 14(RFC 2119、RFC 8174)の意味で解釈します。「参考」と書いた節、例、注記は規範ではありません。

用語意味
スキルSKILL.md(Agent Skills 形式)と、それが使うファイルを含むディレクトリ
スキルディレクトリそのディレクトリ($SKILL_DIR)
契約JSON 文書 skill.contract.json
効果6 区分の副作用(§6)
capabilityスキルが提供する 1 つのツール・コマンド・操作(§7)
生産者契約を書く人・ソフトウェア
検証者契約を検査して結果を報告するソフトウェア
ランナー契約のテストを実行するソフトウェア(§10)
ハーネススキルを読み込むエージェント実行環境(Claude Code、Cursor、Codex、Gemini CLI など)
ポリシーハーネスのポリシー文書(§13)
指摘付録 A のコードを持つエラーまたは警告
署名対象実際に署名するバイト列(§11.1)
作者署名role が author の署名(§11)

2. 対象と対象外#

対象:

  1. 宣言:スキルが何をし、何を必要とし、どんな副作用を持ちうるか。
  2. インストール前の照合:契約 × ポリシー → capability ごとに allow / ask / deny。
  3. 変換:判定結果を Claude Code・Cursor・Codex・Gemini CLI の設定に変換し、HushSpec・Rego に書き出す。

対象外:

  • 実行時の強制。 ハーネスと実行時ポリシーの規格(APS、ACS、HushSpec)に任せます。SkillPact はそれらに情報を渡すだけです。
  • スキルが安全であることの証明。 契約は作者の申告で、テストはその一部を確かめ、署名は誰が作ったかを示すだけです(§18)。
  • スキャン・静的解析。 スキャナーとは競合しません。契約はスキャナーの入力として役立ちます。
  • 配布・レジストリ。
  • Agent Skills の変更。 SKILL.md は変えません。

3. ファイル名・置き場所・形式#

  • 契約のファイル名は skill.contract.json で、SKILL.md と同じディレクトリに置かなければなりません(MUST)。
  • 生産者は契約のために SKILL.md の frontmatter や本文を変えてはなりません(MUST NOT)。SkillPact を知らないハーネスはそのまま動きます。
  • skill.name は frontmatter の name と一致しなければなりません(MUST、NAME_MISMATCH)。frontmatter の name は SKILL.md を含むディレクトリ名と一致しなければなりません(MUST、FM_NAME_DIR。0.7 以上はエラー、それより前は警告。契約を別の場所に置いて検証する場合は対象外)。
  • メディアタイプと名前については付録 D。

4. JSON の扱い#

4.1 パース(I-JSON)#

契約は UTF-8 の JSON(RFC 8259)で、さらに I-JSON(RFC 7493)と次の制限を満たさなければなりません。満たさないものを検証者は CONTRACT_JSON で拒否しなければなりません(MUST)。

  • 重複したキーがない(エスケープを戻したあとで比べる)
  • 整数は ±(2^53−1) の範囲内、数値はすべて有限
  • 文字列とキーに対になっていないサロゲートがない
  • 不正な UTF-8 は拒否
  • 入れ子の深さは 64 まで(最上位を 1 と数える)

理由:パーサーによって解釈が違うと、署名した内容と判定した内容がずれるためです。

5. 文書の構造#

契約は §15 の JSON Schema(Draft 2020-12)に適合しなければなりません(MUST、SCHEMA)。

キー必須内容
$schemaいいえスキーマ URL
contract_versionはい"0.1"〜"0.8"
kindいいえtool(既定)または instructions(実行物なし)
skillはいname、version(SemVer)、native_contract
permissionsはい§6
capabilitiestool では必須§7
requirementsいいえ§8
compatいいえ§9
testsいいえ(L2 に必要)§10
integrityいいえ(L3 に必要)§11
xいいえ拡張。x.<vendor>.* のみ
  • 拡張は x.<vendor> に置かなければなりません(MUST)。vendor 名は ^[a-z0-9][a-z0-9-]*$。それ以外の未知のキーはスキーマエラーです。
  • 検証者は理解できない x の中身を無視しなければなりません(MUST)。ただし §14 の下書きの印は除きます。

6. permissions(6 種類の効果)#

各効果は level(none | scoped | any)、scope(配列)、why、confirm(never | each | session)を持ちます。

効果意味scope の書き方
readファイルやデータを読むパスの glob
write作る・変える・消すパスの glob、remote:<host>/<path>
network他のホストと通信するホストの glob、@local
exec他のプログラムを動かすコマンド名
spendお金を使うサービス名
send人に届く(メッセージ、投稿、メール)宛先の種類・サービス名
  • パス変数:$INPUT $INPUT_DIR $OUTPUT $WORKDIR $SKILL_DIR $TMPDIR。それ以外の $ 変数には UNKNOWN_VARIABLE を出すべきです(SHOULD)。
  • scoped の効果は scope を 1 つ以上持たなければなりません(MUST、SCOPE_EMPTY)。スキル全体の scope は条件付きを含むすべての場合を含まなければなりません(MUST)。
  • spend・send が any なら HIGH_RISK を出さなければなりません(MUST)。
  • @ で始まる scope は予約トークンです。0.8 で定めるのは network の @local(ループバック・プライベート・リンクローカルの IP アドレスと localhost。DNS 名は当てはまらない。付録 C)だけです。未知のトークンには UNKNOWN_SCOPE_TOKEN を出すべきです(SHOULD)。ハーネスや実行時ポリシーに書き出すときは @local をホストのパターンに展開しなければならず(MUST)、表せないもの(IPv6 の範囲や、ホストの glob が当たりうる DNS 名)は lossy として報告しなければなりません(MUST)。

6.1 glob とパス(規範)#

すべての実装は glob を次のとおりに照合しなければなりません(MUST)。fnmatch やシェルの glob の意味を使ってはなりません(MUST NOT)。

  • パスと一般のパターン(read、write、exec、spend、send):* は / 以外の任意の文字列、? は / 以外の 1 文字、セグメント全体が ** なら 0 個以上のセグメントに一致します。末尾の /** は基点そのものにも一致します(a/** は a に一致)。大文字小文字を区別します。
  • ホストのパターン(network):* は 1 つの DNS ラベルの中だけ。先頭の *. は 1 つ以上のラベル(*.example.com は example.com に一致しない)、先頭の **. は 0 個以上のラベル。大文字小文字を区別せず、末尾のドットは無視します。
  • パスの scope(read、write、effect_scopes)は .・..・空のセグメント・バックスラッシュを含んではなりません(MUST NOT、SCOPE_TRAVERSAL)。絶対パスは使えます。
  • 包含(ある scope が別の scope に収まるか。effect_scopes とポリシーのルールで使う):scope の各要素がパターンと同じか、自分のワイルドカードを「同じか広いワイルドカードにしか一致しない文字」として扱ってパターンに一致すれば、含まれるとします。.. などを含む scope は決して含まれません。

7. capabilities#

  • 各 capability は id(一意。DUP_CAPABILITY)、summary、entry、effects を持ちます。
  • entry は cli(配列)、mcp_tool、doc のいずれか。cli 中の $SKILL_DIR/... は実在しなければなりません(MUST、ENTRY_MISSING)。効果があるのに entry がなければ警告 NO_ENTRY。
  • effects の各効果は permissions で none 以外でなければなりません(MUST、UNDECLARED_EFFECT)。
  • effect_scopes は capability ごとに範囲を狭めてよく(MAY)、広げてはなりません(MUST NOT、SCOPE_WIDENED)。
  • conditional_effects[](effect、when、scope):ある場合にだけ起きる効果。これも宣言が必要です。
  • destructive: true には write・send・spend のいずれかを付けるべきです(SHOULD、DESTRUCTIVE_NO_EFFECT)。
  • 任意:idempotent、dry_run、inputs / outputs(JSON Schema。不正なら BAD_SUBSCHEMA)、requires(requirements の名前。UNKNOWN_REQUIREMENT)、requires_features / optional_features(<kind>:<name>。kind は features_check にあること。UNKNOWN_FEATURE_KIND)、mcp_annotations。

8. requirements#

  • binaries[] / runtimes[]:name、version(例 >=4.4)、check、version_regex、optional、when、alternatives、features_check。
  • packages[]:ecosystem、name、version、import、optional。0.8.x 正誤:version があれば、ランナーはテストの前にインストール済みの版を確かめ、合わなければ要件未達として扱わなければなりません(MUST)。任意(optional)のパッケージでも、入っていれば同じです。解釈できない版指定は不合格です。条件はカンマ区切りで、==・!=・>=・<=・>・<・~= を使います(演算子なしは ==)。侵害されると利用者に害が及ぶパッケージは、作者が版を == で固定するべきです(SHOULD)。侵害されたリリースはたいてい新しい版として届くためです(例:PyPI の litellm 1.107.0、2026-10-21)。宣言したパッケージが起動フック(*.pth、sitecustomize.py、usercustomize.py)を入れる場合、ランナーはそれを報告するべきです(SHOULD)。Python は import しなくてもこれらを実行します。参照ランナーが確かめるのは pypi のパッケージだけで、自身のインタープリタで確認します。skills[]:name、version、env、optional。
  • env[]:name、required、secret、description。秘密の値を契約に書いてはなりません(MUST NOT)。

9. compat#

compat.agents.<id>:status(tested | expected | unsupported)、version、tested_at、notes。tested は、そのハーネスで §10 を実行してから名乗るべきです(SHOULD)。ほかに os、interfaces。

10. 適合テスト#

  • setup:新しい $WORKDIR で実行するコマンド。cases[]:id、capability(実在すること。MUST、TEST_UNKNOWN_CAPABILITY)、run、timeout_s、network(既定 false)、env、skip_unless_env、tags、expect(exit_code、stdout_contains、stderr_contains、stdout_json_schema、stdout_json[]、stdout_json_mode、files[]、validate_outputs)。
  • network: true のケースには、permissions.network が none 以外であることが必要です(TEST_UNDECLARED_NETWORK。0.8 からエラー)。
  • ランナーは setup と各ケースを次のサンドボックスで実行しなければなりません(MUST)。
    1. ネットワークなし(network: true のケースを除く)
    2. ファイルシステムは $WORKDIR 以外読み取り専用(write の scope に $SKILL_DIR がある場合だけ $SKILL_DIR も書き込み可)
    3. 環境変数は許可リストのものだけ:PATH、LANG、LC_ALL、TZ、TERM、SkillPact の変数、見つけた依存スキル、ケースの env。HOME と TMPDIR は $WORKDIR の中を指す。skip_unless_env に書かれたホストの変数は、テストを実行する人が許した場合だけ渡す(参照 CLI では --pass-env NAME)。許可がなければそのケースはスキップ(0.8.x 正誤)
    4. 利用者のホームと、ホストの一時・実行時ディレクトリ(/tmp、/var/tmp、/run、/dev/shm)を隠し、ユーザーのファイルを読んだりホストの Unix ソケットに接続したりできないようにする。読み取り専用で見せてよいのは、契約が使うプログラム(exec の scope、requirements、テストと setup のコマンド)を解決したディレクトリとその virtualenv のルートだけ。それ以外の PATH の要素やその親(~/.local など)は、テストを実行する人が足さない限り隠したまま(参照実装では SKILLPACT_SANDBOX_KEEP)(0.8.x 正誤)
    5. 制御端末から切り離した新しいセッションで、標準入力を閉じて実行する(0.8.x 正誤)
  • ランナーはスキルディレクトリの変更を(大きさや時刻ではなく)内容のハッシュで検出し、write の scope に $SKILL_DIR がなければそのケースを失敗にしなければなりません(MUST)。ファイルシステムを隔離できない場合は親ディレクトリも監視し、スキルの外への書き込みを報告しなければなりません(MUST)。
  • ネットワークを隔離できないランナーは L2 を出してはなりません(MUST NOT)。0.8.x 正誤:ファイルシステムを隔離できないランナー(項目 2 と 4。参照実装の unshare -rn へのフォールバックなど)も同じです。L2 には、network: true ではない隔離ケースが 1 つ以上通っていることも必要です。
  • 0.8.x 正誤(exec の記録):ランナーは、各ケースが起動したプログラムを、ケースからは見えず止められない形でサンドボックスの外から記録するべきです(SHOULD)(参照実装は Linux の strace。exec_audit: strace と報告し、使えなければ none)。記録した場合、exec の範囲(capability の effect_scopes.exec があればそれ、なければ permissions.exec)に含まれないプログラムを起動したケースは、プログラムのファイル名で照合して不合格にしなければなりません(MUST)。数えないもの:サンドボックスの起動役と env、ケースのコマンド自身、skill のディレクトリや見つけた依存 skill の中のファイル、そしてケースのコマンドがその場のシェル(sh・bash・dash・zsh に -c)のときに、そのシェルが直接起動した次のユーティリティ:basename, cat, cmp, cp, cut, diff, dirname, echo, false, grep, head, ls, md5sum, mkdir, mv, printf, readlink, realpath, rm, sha1sum, sha256sum, sleep, sort, stat, tail, test, [, touch, tr, true, uniq, wc。これらがさらに起動したものは数えます。この記録は検出であって防止ではありません。ケースが不合格になる時点で、プログラムはすでに実行されています。
  • 0.8.x 正誤(通信先の許可リスト):network: true のケースは、そのケースのネットワーク範囲にあるホストにだけ通信できるべきです(SHOULD)。範囲は capability の effect_scopes.network があればそれ、なければ permissions.network.scope で、capability の条件付きネットワーク効果の範囲も含みます(level: any はすべてのホストを許可)。参照ランナー(bubblewrap)では、こうしたケースに自前のネットワークインターフェースを与えません。外へ出る唯一の道はサンドボックス内 127.0.0.1 の HTTP プロキシで(HTTP_PROXY・HTTPS_PROXY・ALL_PROXY と小文字の同名変数に設定)、これがサンドボックス外のプロキシに中継され、宣言したホストへの CONNECT と平文 HTTP だけを通します。これを行うランナーは、宣言していないホストを求めたケースを不合格にしなければならず(MUST)、求められたホストを報告するべきです(SHOULD)(参照実装:network_hosts、network_egress: allowlist)。プロキシ変数を無視するプログラムはネットワークを使えません(安全側に失敗)。他のランナーモードは network_egress: open と報告します。
  • スキップしたケースは失敗ではありませんが、件数を報告しなければなりません(MUST)。
  • 参照ランナーは Linux では bubblewrap(bwrap)を使い、なければ unshare -rn(ネットワークのみ。fs_isolated: false と報告し、L2 は出しません。0.8.x 正誤)を使います。macOS では Seatbelt(/usr/bin/sandbox-exec、試験的)を使い、書き込みは $WORKDIR(宣言があれば $SKILL_DIR も)だけ、network: true 以外は通信をすべて拒否します。Apple は sandbox-exec を非推奨としていますが、現在も動作し、他のエージェントのサンドボックスでも使われています。0.8.x 正誤:Seatbelt のプロファイルは network: true のケースでも Unix ソケットへの接続(システムの DNS リゾルバを除く)を拒否します。ただし Mach/XPC の問い合わせは許したままなので、ケースが launchd のサービス(open など)にサンドボックスの外での処理を頼めます。このため Seatbelt は試験的のままで、L2 の要件をすべて満たすのは Linux の bubblewrap だけです。Windows には対応する方式がない(WSL2 かコンテナを使う)ため、L2 になりません。

11. integrity と署名#

  • integrity.algorithm は sha256。integrity.files は相対パス → 16 進小文字のハッシュ。検証者は載っている全ファイルを照合しなければなりません(MUST、INTEGRITY_MISMATCH、INTEGRITY_MISSING)。
  • integrity.signatures[]:ed25519 {type, key: "ed25519:<b64>", sig, signer, role} または Sigstore {type, identity, issuer, bundle, instance, role}。
  • role は author(既定)、reviewer、scanner。L3 になれるのは信頼済みの author 署名だけです。有効な reviewer・scanner の署名は証明(attestation)として報告するべきです(SHOULD)。
  • 同じ鍵・identity が同じ契約に 2 回以上署名してはなりません(MUST NOT、DUP_SIGNATURE)。検証者は、その鍵のすべての署名が正しい場合にだけ有効とします。
  • Sigstore の検証者は identity と issuer の両方を信頼リストと照合しなければなりません(MUST)。staging の署名には instance: "staging" を付け(MUST)、本番の信頼リストと照合してはなりません(MUST NOT)。
  • 信頼はポリシーの trusted_keys(ed25519:<b64> または sigstore:<issuer>|<identity>)で決めます。信頼していない鍵の署名で L3 にしてはなりません(MUST NOT)。

11.1 署名対象#

  • contract_version が 0.8 以上:{"contract": C, "role": R} を JCS(RFC 8785)で直列化した UTF-8 バイト列。C は integrity.signatures を除いた契約、R はその署名の role(なければ "author")。role も署名されるので、付け替えると署名が壊れます。
  • 0.4〜0.7:JCS(C)。role は署名されません(旧方式。§18.7)。検証者は SIGNATURE_ROLE_UNSIGNED を警告し、その署名を信頼済みの author 署名として扱ってはなりません(MUST NOT)。0.8 より前の契約は L3 にならず、require_signature も満たしません(0.8.x 正誤)。
  • 0.1〜0.3:旧方式(キーをコードポイント順に並べ、区切りは , :、空白なし、非 ASCII はそのまま UTF-8)。数値は ±(2^53−1) の整数だけ扱えます。それ以外の数値を含む契約は検証できないので、移行して署名し直さなければなりません(MUST)。
  • 方式は contract_version で決まります。integrity.canonicalization は参考情報です。
  • テストベクトル:conformance/vectors/jcs-ed25519.json(シードを公開したテスト用の鍵。本物の署名に使ってはなりません。MUST NOT)。

11.2 ファイルの網羅(0.8 から)#

  • integrity.files にはスキルディレクトリ内のすべての通常ファイルを載せなければなりません(MUST)。除外できるのは skill.contract.json、既定の除外(.git/**、**/.DS_Store)、任意の integrity.exclude のパターンだけです。0.8.x 正誤:Python は署名されたソースではなく未検証のバイトコードを実行しうるため、__pycache__ と *.pyc は除外しなくなりました。ハッシュを取る前にバイトコードを消してください。
  • 次の保護ファイルは必ず載せ、除外できません:SKILL.md、**/SKILL.md、**/CLAUDE.md、**/AGENTS.md、**/GEMINI.md、**/.mcp.json、.claude-plugin/**、.claude/**、.cursor/**、.codex/**、.gemini/**、.agents/**、hooks/**、package.json、pyproject.toml、entry・テスト・setup に $SKILL_DIR/... として出てくるファイル、および(0.8.x 正誤)コードとバイトコードのファイル(*.py、*.pyc、*.pth、*.sh、*.js、*.ts、*.so、*.dll、*.jar、*.wasm など。一覧は参照実装)。契約をスキルディレクトリの外に置いた場合も網羅を確かめます。
  • 載っていないファイル:INTEGRITY_UNLISTED(0.8 からエラー、それより前は警告)。files に SKILL.md がない:INTEGRITY_EMPTY(0.8)。
  • パスは相対の POSIX パスで、.・..・空のセグメント、バックスラッシュ、制御文字を含まず、1024 バイト・32 セグメント以内、全体で 10 000 件以内。スキルディレクトリ内や載っているパスの途中にあるシンボリックリンクは拒否します(INTEGRITY_PATH、全版)。
  • どの版でも、INTEGRITY_UNLISTED か INTEGRITY_PATH の指摘が 1 つでもあれば L3 にしてはなりません(MUST NOT)。

12. MCP との対応#

annotation導き方
readOnlyHintwrite・send・spend がない(条件付きを含む)
destructiveHintdestructive
idempotentHintidempotent
openWorldHintnetwork・send・spend がある

13. ハーネスポリシーと変換#

  • ポリシーは policy-v0.8.json に従います。照合器は capability ごとに decision と decision_worst_case(条件付きの効果を含む)を出さなければなりません(MUST)。0.8.x 正誤:ポリシーは "policy_version": "0.8" とスキーマ policy-v0.8-r1.json を使うべきです(SHOULD)。"0.1" は同じ形式の旧名で、引き続き受け付けなければなりません(MUST)。
  • .. などを含むパスの scope は拒否しなければなりません(MUST)。
  • scope のないポリシーのルールは、その効果のすべての scope(level: any を含む)に当てはまります(0.8.x 正誤)。
  • min_contract_version:これより古い契約は拒否しなければなりません(MUST)。
  • require_signature:照合器はファイル(§11.2 の網羅を含む integrity)を確かめ、信頼済みの author 署名を求めなければなりません(MUST)。満たさなければ拒否します。

13.1 変換#

  • policy-compile は Claude Code・Cursor・Codex・Gemini CLI の設定を出力し、各ハーネスの公開スキーマ(なければ文書から起こしたスキーマ)で検証します。変換先が表せないものは lossy に挙げなければなりません(MUST)。
  • 提案 #12(0.8.x):コマンド単位の規則を持つ変換先(Claude Code の Bash(...)、Cursor の Shell(...)、Gemini CLI の commandPrefix)では、変換器は exec の範囲にある各プログラムに、そのプログラムだけを範囲とする exec 効果の判定(ポリシーの規則、既定値、skill の confirm)を与えるべきです(SHOULD)。効果全体で 1 つの最悪ケースにまとめません。条件付きの効果だけが実行するプログラムには、そのプログラム自身の判定を与えます。
  • 変換先が deny や ask を表せない場合、出力は判定と同じかそれより厳しくなければなりません(MUST)(例:Codex は approval_policy: on-request。never にはしない)。変換した設定は条件付きの効果を含む decision_worst_case に従います(0.8.x 正誤)。
  • 0.8.x 正誤:コマンド単位の allow(例:Claude Code の Bash(python3 *))によって、宣言したプログラムを任意の引数で実行できるようになる場合、変換器はそれを lossy に挙げなければならず(MUST)、そのプログラムが任意のコードを実行できるもの(インタープリタやシェル)であればその旨も書くべきです(SHOULD)。そうした allow は exec: any と同じ広さになるためです。
  • export --format hushspec|rego は実行時ポリシーの文書を出力します。

13.2 (欠番)#

0.8 ではこの番号を使いません。§13.3 はすでに参照されているため番号を変えません。

13.3 組み合わせ(0.8.x、追加)#

入れたスキルは、同じエージェントの中で動きます。あるスキルが読んだデータは、エージェントの文脈を通って別のスキルに渡りえます。スキルを一つずつ隔離しても、この流れは止まりません。この節は任意(OPTIONAL)で、単独の契約のレベルやポリシーの結果は変えません。

  • スキルの組の実際の効果は、宣言されたすべての効果の和集合です。条件付きの効果も含め(最悪の場合)、効果ごとに scope と、それを持つスキルを示します。
  • 危険な組み合わせ(パス)。組み合わせに対応すると言うツールは、少なくとも次を検出し、それぞれの役割を担うスキルを示さなければなりません(MUST)。
パス組に含まれるもの重大度
exfiltration(持ち出し)秘密の scope(~/.ssh、.env、認証情報、トークン、鍵など)、広い scope(/**、~/**)、level: any のどれかの read、かつ @local 以外の network か send高
persistence(居座り)$WORKDIR・$OUTPUT・$TMPDIR の外への write(または level: any)、かつ exec中
spend_untrustedspend、かつ ファイルの照合に通る信頼済みの author 署名がないスキル(2 つ以上の組。0.8.x 正誤:ファイルが §11 に通らない契約の署名は数えない)高

役割は 1 つのスキルが担うことも、別々のスキルが担うこともあります(cross_skill)。秘密の scope のパターンは参照実装とベクトル conformance/vectors/compose.json にあります。

  • ポリシー:任意の compositions(スキーマ policy-v0.8-r2.json)で、パスごとに allow・ask・deny を決めます。照合器に複数の契約を渡すと、スキルごとの結果はそのままで、判定のあるパスごとに 1 件を足します。組の判定は、その中でいちばん厳しいものです。compositions がなければ、スキルを一つずつ確かめた結果と同じです。
  • 変換:ハーネスの設定はツールごとなので、スキルをまたぐ条件は書けません。組が ask か deny のパスを作るときは、そのパスに関わるスキルの効果をすべて ask 以上で出力し(MUST)、そのパスを lossy に挙げなければなりません(MUST)。
  • 参照 CLI:skillpact compose <dir>...、policy-check <dir>... <policy>、policy-compile <dir>... <policy> --target T。

14. 変換と下書き#

  • convert は MDA Open Spec の requires、AutoVault の capabilities と相互に変換します。書き出しは lossy と、元の契約とその sha256 を示します。
  • 取り込みや init の下書きは、推測した箇所を x.import.uncertain / x.init.uncertain に挙げ、TODO(...) を使うことがあります。こうした契約は未確認の下書きで、UNCONFIRMED_DRAFT(0.8 からエラー)になります。人が確認して印を消す必要があります。0.8.x 正誤(参考、参照実装の init):capability は CLI のサブコマンドごと(console script のモジュールと scripts/ の argparse の add_parser)、MCP のツールごと(@*.tool の関数、Tool(name=...))、指示だけのスキルなら SKILL.md の一般的でない ## 見出しごとに作ります。doctor・validate・plan などの読むだけの動詞は read・exec だけにし、network の scope は見つかった URL から、なければ TODO(init) にします。

15. スキーマ#

  • 契約:schema/v0.8.json($id https://kajisho5.github.io/skillpact/schema/v0.8.json)。ポリシー:schema/policy-v0.8.json。改訂版として schema/policy-v0.8-r1.json(policy_version "0.8"、0.8.x 正誤)と schema/policy-v0.8-r2.json(compositions を追加、§13.3)があります。公開したスキーマファイルは書き換えません。

16. 適合#

16.1 レベル(契約について)#

  • L1 宣言済み:検証者のエラーが 0。
  • L2 テスト済み:L1 に加え、§10 のサンドボックスで全ケースが通り、ネットワークを隔離したケースが 1 つ以上ある。
  • L3 署名済み:L2 に加え、全ファイルを網羅した integrity が一致し(§11.2)、信頼済みの鍵・identity による有効な作者署名がある。

L3 の意味は「このファイル一式は、あなたが信頼する人が署名したもので、宣言したテストが隔離環境で通る」ということです。スキルが安全だという意味ではありません。

16.2 適合クラス(ソフトウェアについて)#

クラス要件
生産者§3〜§11 とスキーマを満たす契約を出す
検証者§3〜§11 と §14 の MUST をすべて検査し、付録 A のコードで報告し、適合スイートに合格する
ランナー§10 のサンドボックス、環境変数の許可リスト、内容ハッシュによる変更検出、スキップの報告
ポリシー照合器§13 の判定、require_signature と min_contract_version
変換器§13.1(lossy を含む)
ハーネスdecision_worst_case に従い、実行前に integrity を確かめ直すべき(SHOULD)

16.3 適合スイート#

conformance/manifest.json と conformance/cases/<id>/(0.8 と 0.8.x 正誤で 49 ケース)。適合を名乗る検証者は全ケースに合格しなければなりません(MUST):python3 conformance/run.py --cmd '<validator> {dir}'。0.8 のケースは conformance/gen_v08.py が作ります。Python の参照実装と TypeScript 実装の両方が全ケースに合格しています。

17. バージョン・安定性・非推奨#

  • 検証者は知っているすべての版を受け付け、知らない major 版を拒否しなければなりません(MUST、CONTRACT_VERSION_UNSUPPORTED)。0.x の間は、知らない minor 版も知らない major 版として扱います。
  • 1.0 以降:minor 版は追加だけ(任意フィールド、新しいコード、新しい enum 値)。それ以外は新しい major 版が必要です。知らない minor 版は CONTRACT_VERSION_NEWER を出して処理してよい(MAY)。
  • 非推奨:削除の少なくとも 1 minor 版前に告知し、検証者は警告するべきです(SHOULD)。
  • skill.version は SemVer。permissions を広げる変更では major を上げ(SHOULD)、ハーネスは承認し直しを求めるべきです(SHOULD)。
  • migrate は契約を新しい版に上げ、内容が変われば署名を外します。署名・公開はしません。

18. セキュリティの考慮事項#

18.1 脅威モデル#

守る対象:利用者とそのハーネス(ファイル、認証情報、通信、お金、人へのメッセージ)。信頼するもの:検証者、ランナー、ハーネス、利用者が trusted_keys に入れた鍵。信頼しないもの:スキルの作者、配布経路、ミラー、契約の中身。

攻撃者できること対策残る危険
悪意ある作者効果を少なく申告する、テストのときだけ行儀よくする隔離テスト、サンドボックス、最悪ケースの判定テストに出ない経路。実行時の強制が必要
配布経路・ミラーファイルや契約の差し替え全ファイルのハッシュと署名、L3 は信頼済みの鍵だけ信頼済みの鍵の漏えい
署名の付け替えreviewer の署名を author に見せかける0.8 から role も署名0.4〜0.7 の契約(§18.7)
版の差し戻し古くて緩い版の契約を出す知らない版の拒否、min_contract_version承認した版を記録しないハーネス
依存先依存スキルやパッケージの改ざんrequirements での宣言依存先の中身は範囲外
文字列による指示の注入why や summary に指示を書く判定は構造化された項目だけで行う自由文をモデルに渡すハーネス

18.2 宣言は自己申告#

L1 は整合性しか示しません。ハーネスは L1 だけを根拠に、効果を伴う capability を自動で許可するべきではありません(SHOULD NOT)。実行時の強制と組み合わせるべきです(SHOULD)。

18.3 integrity と TOCTOU#

確認してから実行するまでにファイルが変わるおそれがあります。ハーネスは確認したコピーを読み取り専用で実行するか、実行直前に確かめ直すべきです(SHOULD)。

18.4 鍵と identity#

秘密鍵を契約、リポジトリ、ログに含めてはなりません(MUST NOT)。鍵を替えるときは、少なくとも 1 回のリリースで新旧両方の鍵で署名します。漏えいしたら利用者はその鍵を trusted_keys から外さなければなりません(MUST)。Sigstore の identity はワークフローのパスと ref まで完全に照合し、issuer や組織名だけで照合してはなりません(MUST NOT)。

18.5 パース#

§4.1 がパーサー間の違い(重複キー、大きな整数、サロゲート、深さ)をなくします。

18.6 テストの実行#

テストの実行はスキルのコードを動かすことです。setup と run は信頼できない入力として扱い、§10 に従います。利用者の認証情報は skip_unless_env に書かれた変数を除いて渡してはなりません(MUST NOT)。

18.7 旧版#

0.8 より前の契約は role を署名せず、全ファイルの網羅も求めません(載っていないファイルは警告ですが、L3 にはなりません)。ポリシーには min_contract_version: "0.8" を設定するべきです(SHOULD)。

19. プライバシーの考慮事項#

  • 契約には、任意の signer 名と Sigstore の identity(メールアドレスや CI ワークフローの URL であることが多い)を除き、個人情報は含まれません。個人のメールアドレスを公開したくない作者は、役割用・プロジェクト用の identity を使うべきです(SHOULD)。Sigstore の記録は公開の透明性ログにも残ります。
  • 秘密の値を契約に書いてはなりません(§8)。
  • 検証者とブラウザのチェッカーはオフラインで動きます。チェッカーのページは何も送信しません。
  • テストの実行には許可リストの環境変数だけが渡ります(§10)。

20. 相互運用#

  • Agent Skills:SKILL.md は変えず、名前はその規則に従います。
  • MCP:annotations(§12)、mcp-check。
  • ハーネス設定:Claude Code、Cursor、Codex、Gemini CLI(§13.1)。それぞれ表せないものがあります。
  • 実行時ポリシー:HushSpec、Rego(APS・ACS 向け)。
  • 他の形式:MDA Open Spec、AutoVault(§14)。OWASP Agentic Skills Top 10 との対応:spec/owasp_mapping.md(部分的な対応であることを正直に記載)。

21. 参照文献#

規範:RFC 2119、RFC 8174(BCP 14)、RFC 8259(JSON)、RFC 7493(I-JSON)、RFC 8785(JCS)、RFC 8032(EdDSA / Ed25519)、JSON Schema 2020-12、Agent Skills 仕様(https://agentskills.io/specification)、Semantic Versioning 2.0.0。

参考:Sigstore、MCP tool annotations、OWASP Agentic Skills Top 10(https://owasp.org/www-project-agentic-skills-top-10/)、HushSpec、Agent Policy Specification、Microsoft Agent Control Specification、OPA / Rego、MDA Open Spec、AutoVault、bubblewrap、各ハーネスの文書(Claude Code、Cursor、Codex、Gemini CLI。2026-10-22 時点)。

付録 A. 指摘コード#

重大度はコードと版ごとに決まっています。新しいコードは提案の手続き(GOVERNANCE.md)でのみ追加します。エラーがあれば L1 になりません。警告は L1 を妨げません。

コード重大度節意味
SKILL_MD_MISSINGエラー全体SKILL.md がない
FRONTMATTER_MISSINGエラー全体frontmatter がない
FM_NAMEエラー全体name が Agent Skills の規則に違反
FM_DESCRIPTIONエラー全体description がない・1024 字超
FM_COMPATエラー全体compatibility が 500 字超
FM_NAME_DIRエラー ≥0.7, それより前は警告§3name とディレクトリ名が違う
CONTRACT_MISSINGエラー全体契約ファイルがない
CONTRACT_JSONエラー§4.1I-JSON でない(重複キー、大きな整数、サロゲート、深さ、文字コード)
CONTRACT_VERSION_UNSUPPORTEDエラー§17知らない major(0.x では minor)版
CONTRACT_VERSION_NEWER警告§17新しい minor 版(1.0 以降)
SCHEMAエラー§5スキーマ違反
NAME_MISMATCHエラー§3skill.name と frontmatter の name が違う
DUP_CAPABILITYエラー§7capability の id が重複
UNDECLARED_EFFECTエラー§7使う効果が permissions で none
BAD_SUBSCHEMAエラー§7inputs/outputs が不正なスキーマ
UNKNOWN_REQUIREMENTエラー§7requires が requirements にない
ENTRY_MISSINGエラー§7入口ファイルがない
UNKNOWN_FEATURE_KINDエラー§7feature の kind が未定義
SCOPE_EMPTYエラー§6scoped なのに scope が空
SCOPE_WIDENEDエラー§7effect_scopes が permissions より広い
SCOPE_TRAVERSALエラー§6.1パス範囲に . / .. / 空 / \
TEST_UNKNOWN_CAPABILITYエラー§10テストが未知の capability を参照
TEST_UNDECLARED_NETWORKエラー ≥0.8, それより前は警告§10network 宣言なしの network テスト
UNCONFIRMED_DRAFTエラー ≥0.8, それより前は警告§14下書きの印が残っている
INTEGRITY_MISSINGエラー§11載っているファイルがない
INTEGRITY_MISMATCHエラー§11ハッシュが違う
INTEGRITY_PATHエラー (載っていないリンク: 警告 <0.8)§11.2不正なパス・シンボリックリンク・上限超え
INTEGRITY_UNLISTEDエラー ≥0.8, それより前は警告§11.2integrity に載っていないファイル
INTEGRITY_EMPTYエラー (0.8+)§11.2files に SKILL.md がない
SIGNATURE_INVALIDエラー§11署名が検証できない
SIGNATURE_ROLE_UNSIGNED警告§11.10.8 より前の契約の署名。role が署名されず L3 にならない(0.8.x)
DUP_SIGNATUREエラー§11同じ鍵が 2 回以上署名
SIGSTORE_UNVERIFIED警告§11Sigstore を検証できない実装
HIGH_RISK警告§6spend/send が any
UNKNOWN_SCOPE_TOKEN警告§6未定義の @ トークン
UNKNOWN_VARIABLE警告§6未定義の $ 変数
DESTRUCTIVE_NO_EFFECT警告§7destructive なのに write/send/spend がない
NO_ENTRY警告§7効果があるのに entry がない
UNUSED_PERMISSION警告§6どの capability も使わない権限
NO_TESTS警告§10テストがない
UNTESTED_CAPABILITY警告§10テストのない capability
BODY_LONG警告§3SKILL.md 本文が 500 行超

付録 B. 例#

最小(説明だけのスキル):

{"contract_version": "0.8", "kind": "instructions",
 "skill": {"name": "style-guide", "version": "1.0.0"},
 "permissions": {"read": {"level": "none"}, "write": {"level": "none"}, "network": {"level": "none"},
                 "exec": {"level": "none"}, "spend": {"level": "none"}, "send": {"level": "none"}},
 "capabilities": [{"id": "guide", "summary": "writing guidance", "effects": []}]}

テスト付きのツール:

{"contract_version": "0.8", "skill": {"name": "thumb", "version": "1.2.0"},
 "permissions": {"read": {"level": "scoped", "scope": ["$INPUT"]}, "write": {"level": "scoped", "scope": ["$OUTPUT"]},
   "network": {"level": "none"}, "exec": {"level": "scoped", "scope": ["python3"]},
   "spend": {"level": "none"}, "send": {"level": "none"}},
 "capabilities": [{"id": "make", "summary": "make a thumbnail", "effects": ["read", "write", "exec"],
   "entry": {"cli": ["python3", "$SKILL_DIR/scripts/thumb.py", "$INPUT", "$OUTPUT"]}}],
 "tests": {"cases": [{"id": "basic", "capability": "make", "run": ["python3", "$SKILL_DIR/scripts/thumb.py", "--selftest"],
   "expect": {"exit_code": 0}}]}}

署名済みの完全な例:samples/(L3 の 4 スキル)。テストベクトル:conformance/vectors/。適合ケース:conformance/cases/。

付録 C. @local の展開#

0.8.x 正誤:@local に当てはまるのは localhost と IP アドレスの表記だけです。IPv4 は 127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16(10 進のドット表記、先頭ゼロなし)、IPv6 は ::1、fe80::/10、fc00::/7(角かっこは可。ゾーン ID や IPv4 埋め込みは不可)。DNS 名は決して当てはまりません(*.local、10.0.0.com、127.0.0.1.example.com)。ベクトル:conformance/vectors/local-hosts.json。ハーネスのホスト glob(127.*.*.* など)に変換すると DNS 名にも当たりうるうえ IPv6 の範囲は書けないため、lossy で報告します。

付録 D. メディアタイプとファイル名(登録についての注記)#

  • ファイル名:skill.contract.json(固定、SKILL.md の隣)。
  • メディアタイプ:現在は application/json を使います。専用のタイプ(例 application/skillpact+json)は IANA に登録していません。1.0 の後に検討します。それまで実装は特定のメディアタイプに頼ってはなりません(MUST NOT)。
  • スキーマの URL は版ごとに固定です。

付録 E. 0.8 の変更点#

全ファイルの網羅とパスの規則(§11.2)、署名対象への role の追加(§11.1)、DUP_SIGNATURE、I-JSON のパース(§4.1)、規範としての glob と SCOPE_TRAVERSAL(§6.1)、setup のサンドボックス化・環境変数の許可リスト・内容ハッシュでの変更検出(§10)、TEST_UNDECLARED_NETWORK、UNCONFIRMED_DRAFT、ポリシーの min_contract_version と require_signature でのファイル確認(§13)、lossy を伴うより厳しい変換(§13.1)、英語版を規範に変更。これまでの履歴:CHANGELOG.md。

原稿を編集