AI開発
そのPASSは、実行許可ではない。
Agent Role Contracts v0.1が検査すること、検査しないこと
公開日:2026年9月30日 更新日:2026年9月30日 著者:飯田 友広(Tomohiro Iida)
この記事の結論
PASSはv0.1.0の宣言整合性チェックの結果であり、実行許可そのものではない。
validateはbundleレベルのロール・権限・ルート整合性・レビュアー宣言を検査し、explainはtask routingとwrite scopeの検査を追加する。引き継ぎの整合性はhandoffコマンドが引き継ぎ文書を受け取ったときだけ検査する。
終了コードは0(整合)・1(宣言違反)・2(CLI/ファイルエラー)の3種類で、実行の可否そのものとは別の意味を持つ。
2026年9月30日、npmレジストリへの登録とフレッシュインストールの検証が完了し、実際にインストールして動かせる状態になった。
Scope Gate・Independent QC・マージやデプロイの権限は、このチェッカーの範囲外にあり、既存のページが担当する。
AIエージェントに仕事を渡す前に、誰がどの役割を持ち、何を書き換えてよく、どのタスク種別を誰が担当し、誰がレビューするかを、あらかじめ宣言しておく開発チームが増えている。Agent Role Contractsは、その宣言をオフラインで検査するだけのツールだ。何かを実行することはない。
このチェッカーをエージェント実行の手前に置こうとしている人が最初に知っておくべきなのは、PASSがどこまでを保証するかという範囲だ。v0.1.0(コミットc987c44…)の時点で、PASSが保証する範囲はかなり狭い。その狭さは意図したものだ。PASSは、実行したコマンドの範囲内で、宣言に矛盾がなかったことしか意味しない。validateはbundleレベルのrole・authority・route整合性・reviewer宣言・relation cycle・knowledge referenceを検査する。explainはそれにtask routingとwrite scopeの検査を追加する。引き継ぎ(handoff)の整合性は、引き継ぎ文書を渡したときだけ動く独立したhandoffコマンドが検査する。エージェントが動き出してから起きることについて、PASSは何も語らない。
GitHubのv0.1.0は公開済みで、npmレジストリへの登録とインストール検証も完了している。 Agent Role Contractsはsuirindo/agent-role-contractsとしてMITで公開され、正確なHEADc987c44f4e187a8ec4c8173142dfe1806f8b5125とタグv0.1.0に固定されている。2026年9月30日、@netsujo/agent-role-contracts@0.1.0をnpmレジストリから実際にインストールし、レジストリ配布物のSHA-256がGitHubリリース資産のSHA-256(12c07906…)と一致することを確認した。
スターターを動かす
v0.1.0のスターター一式は、2つのroleを宣言する。implementerは宣言した範囲内でファイルを書き換えられる。reviewerは読み取り専用で、implementerとは異なるrole IDとして宣言される。スターターに含まれる唯一のタスクはimplementerへルーティングされる。
package.jsonが要求するNode.jsは22.5以上で、実行時依存関係もインストールスクリプトも宣言されていない。READMEにはAPIキーもネットワークも不要だとある。npmレジストリが未公開だった段階では、この記事はリポジトリ直下のコマンドしか示せなかった。現在はnpm install @netsujo/agent-role-contracts@0.1.0でインストールしたパッケージから、同じスターターをそのまま実行できる。
npm install @netsujo/agent-role-contracts@0.1.0
node node_modules/@netsujo/agent-role-contracts/bin/agent-role-contracts.mjs validate \
--bundle node_modules/@netsujo/agent-role-contracts/examples/starter-bundle.json
node node_modules/@netsujo/agent-role-contracts/bin/agent-role-contracts.mjs explain \
--bundle node_modules/@netsujo/agent-role-contracts/examples/starter-bundle.json \
--task node_modules/@netsujo/agent-role-contracts/examples/starter-task.json --format text2026年9月30日、Node.js v24でこの手順をそのまま実行した。validateは"valid": trueを返し、explainのテキストレポートには次の一行が出力された。
PASS: explain (declarations only; execution NOT authorized)両方とも終了コードは0だった。括弧の中はPASS自身が付けた注記であり、JSON出力ではさらに7つの結果フィールドがすべてfalseになる。execution_authorized、runtime_enforcement、identity_verified、evidence_verified、source_files_checked、sensitive_data_scanned、output_schema_validatedだ。
スターターには、あえて失敗するタスクも用意されている。implementerに許可されていない範囲への書き込みを要求するタスクだ。
node node_modules/@netsujo/agent-role-contracts/bin/agent-role-contracts.mjs explain \
--bundle node_modules/@netsujo/agent-role-contracts/examples/starter-bundle.json \
--task node_modules/@netsujo/agent-role-contracts/examples/starter-task-outside-scope.json --format text結果はFAIL、ルールコードはTASK_WRITE_SCOPE_OUTSIDE_AUTHORITY、終了コードは1だった。公開版のテストが期待する挙動と同じである。
PASSの中身にある規則
v0.1.0(c987c44…)に実装されている規則は、次の領域に分かれる。この表はこの正確なリリースの一覧であり、将来のバージョンでは変わりうる。
| 規則の領域 | v0.1.0の規則コード |
|---|---|
| ロール参照と循環参照 | ROLE_REFERENCE_UNKNOWN, ROLE_RELATION_CYCLE |
| IDとエイリアスの重複 | ROLE_ID_DUPLICATE, ROLE_ALIAS_COLLISION, KNOWLEDGE_ID_AMBIGUOUS, ROUTE_AMBIGUOUS |
| 権限の矛盾 | AUTHORITY_CONTRADICTION |
| 明示ルート | TASK_TYPE_UNROUTED, ROUTE_ROLE_UNKNOWN, ROUTE_ROLE_INACTIVE |
| レビュアー宣言 | SELF_REVIEW_DECLARED, REVIEWER_NOT_READ_ONLY |
| タスク入力の必須・条件付き | TASK_INPUT_REQUIRED, CONDITIONAL_INPUT_CONTRACT, INPUT_REQUIRED_OPTIONAL_OVERLAP |
| タスクの書き込み範囲 | TASK_WRITE_SCOPE_INVALID, TASK_WRITE_SCOPE_OUTSIDE_AUTHORITY |
| 登録済みナレッジ参照 | KNOWLEDGE_REFERENCE_UNKNOWN, KNOWLEDGE_URI_INVALID |
| ランタイム固有宣言(有限のチェック) | RUNTIME_SPECIFIC_DECLARATION |
引き継ぎの整合性(handoffコマンドのみ) | HANDOFF_TASK_MISMATCH, HANDOFF_OBJECTIVE_MISMATCH, HANDOFF_ROLE_OUTSIDE_ROUTE, HANDOFF_SELF, HANDOFF_RELATION_UNDECLARED, HANDOFF_REVIEW_ROUTE, HANDOFF_COMPLETE_UNRESOLVED, HANDOFF_BLOCKER_MISSING |
公開版が受け入れられたのは、決定的テスト、パッケージとフレッシュインストールのスモーク、宣言されたホスト型プラットフォームでの実行、独立したレビューを経たあとだ。個々のルールコードを、文書化された検査を超える範囲まで読み込まないほうがいい。
コマンドごとに検査する範囲が違う
3つのCLIコマンドは受け取る入力が違い、それぞれ入力が許す規則しか適用できない。
validateはbundle(--bundle)と出力形式(--format、省略可)を受け取る。ロールとルートの整合性、権限の矛盾、レビュアー宣言、循環参照、ナレッジ参照といったbundleレベルの規則を検査する。タスク文書を持たないため、TASK_TYPE_UNROUTEDやTASK_WRITE_SCOPE_INVALID、TASK_WRITE_SCOPE_OUTSIDE_AUTHORITYのようなタスク依存の検査は動かない。explainはタスクを1つ追加で受け取る(--bundle、--task)。そのためタスクのルーティングと書き込み範囲の検査も動く。handoffはbundle、タスク、引き継ぎ文書の3つを受け取る(--bundle、--task、--handoff)。引き継ぎ文書を検査できるのはこのコマンドだけで、HANDOFF_*のコードを返せるのもこのコマンドだけだ。
つまり、スターターのexplainがPASSしても、引き継ぎについては何も語っていない。explainには引き継ぎ文書を読む経路がなく、--handoffを渡すとCLI_ERROR、終了コード2になる。スターター自体にも引き継ぎ用のfixtureは含まれていない。公開版が引き継ぎの例として使っているのは、より大きなbundleであるteam.jsonだ。coordinator、implementer、reviewerの3ロールを宣言している。
node node_modules/@netsujo/agent-role-contracts/bin/agent-role-contracts.mjs handoff \
--bundle node_modules/@netsujo/agent-role-contracts/examples/team.json \
--task node_modules/@netsujo/agent-role-contracts/examples/task.json \
--handoff node_modules/@netsujo/agent-role-contracts/examples/handoff.json --format text2026年9月30日の実行ではPASS: handoff (declarations only; execution NOT authorized)が出力され、終了コードは0だった。役割の間で引き継ぎ文書を渡して仕事を移す運用なら、その文書1つずつをhandoffへ通す必要がある。explainの結果はbundleとタスクだけをカバーし、そこで止まる。
書き込み範囲とhuman_only
書き込み範囲の検査は、タスクがルーティングされた先の実行役がauthority_modeとしてwrite_scopedまたはoperatorを宣言している場合にだけ動く。対象のタスクでは、inputs.scopeにポータブルな相対スコープを1つだけ持たせる必要がある。文字・数字・.・_・-で構成され、先頭は文字か数字、.や..だけのセグメントを含まず、末尾だけ/**にできる。これ以外の値はTASK_WRITE_SCOPE_INVALIDになる。書式は正しくても、実行役のallowed_write_scopesのどれにも含まれない場合はTASK_WRITE_SCOPE_OUTSIDE_AUTHORITYになる。
「含まれる」は2つの宣言のあいだの文字列比較にすぎない。要求されたスコープが、宣言済みスコープと完全に一致するか、末尾が/**で終わる宣言済みスコープの配下にあるかのどちらかだ。チェッカーはファイルパスに一切触れず、globも展開せず、何の権限も付与しない。
human_onlyは機械による権限をゼロにするロールを表す。宣言上、capabilitiesとallowed_write_scopesの両方が空配列になる。人間が判断・承認する地点を示すロールであり、機械が何かを変更する権限は持たない。human_onlyのロールにどちらかの配列へ値を入れると、AUTHORITY_CONTRADICTIONになる。
PASSの外側にあるもの
7つのfalseは、チェッカー自身が「これはやっていない」と出力の形で示しているものだ。PASSは、次の問いも未解決のまま残す。
- 計画した作業が正しいか、安全か、そのモデルに実際にできることか
- bundleで名指しされたレビュアーが、実際のレビュー時点で独立して動いたか
- 身元や証拠が本物か
- ソースファイルを読んだか、秘密情報を探したか
- ランタイムの権限が実際に強制されたか、本番へmergeやdeployをしてよいか
- チェッカー自身に抜けやバグがないか
CLIのヘルプによれば、どのコマンドもエージェントを起動せず、evidenceコマンドやネットワークリクエストを実行せず、ファイルへの書き込みも行わない。ナレッジのURIは取得されないままで、evidenceコマンド文字列は不活性なデータとして扱われる。候補のテストの1つは、コア実装をメモリ上のVMへ読み込みfetchを封じたうえでvalidate・explain・handoffを実行し、アプリケーションI/Oがゼロであることを確認している。
このチェッカーの作り自体に由来する制約もある。スキーマ検証はJSON Schema Draft-07のキーワードのうち閉じた部分集合に限られており、それ以外のキーワードを使ったスキーマは明示的に失敗する。ランタイム固有の検査が把握しているのは、少数の設定キーと.claude・.codexのパス形式だけだ。どれにも当てはまらなければ検査は通過するが、その通過が意味するのはそれだけである。宣言のランタイム中立性を保証せず、セキュリティ上の問題やシークレット、マルウェア、プロンプト安全性もスキャンしない。
終了コードと拒否の実例
CLIのヘルプには3つの終了コードが定義されている。
| 終了コード | CLIヘルプの表現 | 自動化への意味 |
|---|---|---|
0 | declared contracts consistent | 実行したコマンドが適用したすべての規則を満たした |
1 | invalid declaration | 1つ以上の規則・スキーマ違反が見つかった |
2 | CLI/file error | 検査自体が走らなかったため、宣言についての判定は存在しない |
準備段階の検証と、公開候補の最終受け入れの両方を通して確認された拒否の実例。
typeに明示ルートがないタスクはTASK_TYPE_UNROUTED(「明示ルートがなく、フォールバックも実行されない」)、終了コード1になった。チェッカーは既定の実行役を勝手に選ばない。examples/invalid-self-review.jsonのfixtureはSELF_REVIEW_DECLAREDとREVIEWER_NOT_READ_ONLY、終了コード1になった。- 未知のフィールドを持つタスクはスキーマエラー、終了コード1になった。
- 存在しないパスを指すタスクファイルは
CLI_ERROR、終了コード2になった。 explainへ--handoffを渡すとCLI_ERROR、終了コード2になった。
パイプラインでは、終了コード0だけを次の工程へ通す。1なら宣言を書いた側へ差し戻す。2ならコマンドラインと入力ファイルを確認する。この終了コードは宣言についての判定を何も持たない。
ランタイムの権限やコードレビューはすでにあるのだから、宣言まで検査する意味は薄いという見方もあるだろう。この検査が加えているのは、タイミングと、結果をきれいに分ける仕組みだ。ロールが自分の仕事をレビューする、書き込み範囲が許可された権限の外にある、タスク種別にルートがない、といった自己矛盾した計画を、エージェントやプロバイダ、ファイルシステムへの操作が起きる前に止める。終了コード1と2は「宣言が誤っている」と「検査自体が走らなかった」を区別したまま保つ。もっとも、これ自体は何かを強制する仕組みではない。ワークフロー側が終了コード0以外での実行開始を拒まない限り、この検査を走らせても何も変わらない。
隣接する問いを担当する既存ページ
周辺の概念については、Netsujoはすでにページを公開しており、このチェッカーはそこへ新しい用語を持ち込まない。各行が、隣接する問いを担当するページと、PASSがその問いに答えられない理由を示す。
| ページ | 担当する範囲 | PASSがそこに答えない理由 |
|---|---|---|
| Agent Harnessとは | 実行環境そのもの。Instructions、入力契約を持つTools、Context、実行ループ、Guardrails、Observability、Recovery | Harness全体の設計や入力契約、Guardrails、実行環境の準備はそちらが担当し、ここでは繰り返さない。そうした環境の内側で、このチェッカーは実行前の宣言検査を1つ提供するだけだ。 |
| State・Authority・Evidence | 作業がどこにあり、誰が何を変更してよく、対象について何が確認済みか | チェッカーが比較するのはbundleが宣言する権限だけであり、作業がどこまで進んだかは見ていない。PASSは、何かが実行された、あるいは検証されたという証拠にはならない。 |
| ChatGPT・Claude Code・Codexの分業開発 | Task Contract。goal、scope、non_goals、invariants、acceptance_criteria、evidence、stop_conditions | チェッカーのタスクスキーマが求めるのはschema_version・id・type・objective・inputs(スカラー値だけを持つフラットなオブジェクト)・acceptance_criteriaの6項目だ。non_goals、invariants、stop_conditionsはそこに含まれず、PASSはTask Contractが完成しているかどうかについて何も述べない。 |
| Controller・Evidence Ledger・GateとClaude CodeとCodexを同じリポジトリで並列運用する | 実行後のScope Gate。ブランチ、許可されたパス、変更の所有権を、実際のgit diffと突き合わせて確認する | チェッカーが比較するのは、実行前の要求スコープと宣言済みのallowed_write_scopesだ。Scope Gateはそのあとに実際に変わったファイルを見ており、PASSはその差分について何も予測しない。 |
| Independent QCとは | 別のruntime・別のcontextによる、同じ対象へのレビュー | チェッカーが確認できるのは、読み取り専用のレビュアーがimplementerとは異なるrole IDとして宣言されていることまでだ。異なるrole IDが別runtime・別session・別人物へ割り当てられたかは検証しない。独立性そのものはレビュー行為に属し、実際のレビューでしか示せない。 |
このチェッカーはNetsujo Agent OS(日本語のみのページ)でもない。Netsujo自身のAIエージェント開発を支える社内運用基盤だ。候補版のREADMEには、このパッケージは「ランタイムのサンドボックスでも実行コントローラでもなく、既存の社内Agent OSの代替でもない」とあり、続けて「このパッケージは社内設定を一切読み込まない」と明記されている。v0.1のリリース計画が引いた境界は「現行の宣言チェッカーだけを出荷する」というものだ。エージェントの起動やプロバイダ呼び出し、ランタイムやOSレベルの権限強制、身元・証拠の認証、マージ・デプロイの権限、ランタイムアダプタ、コンソール、課金は、すべてv0.1の外にある。
公開状況
ソース権利のゲートはv0.1.0の対象範囲について閉じており、NetsujoはMITでの公開を承認した。非公開の準備用リポジトリをそのまま公開する代わりに、新しい公開履歴を作成している。公開候補は正確にc987c44f4e187a8ec4c8173142dfe1806f8b5125、tree 54d40645161944190e37a3ffc26a110fade580fe、タグv0.1.0に固定されている。
この候補は198件中198件の決定的テストに通過した。pack→fresh install→ルートAPI→スキーマのインポート→通常のCLI→意図的なfail-closedのスモークという順番も通過している。ホスト型のマトリクスは、Ubuntu/Node 22.5、Ubuntu/Node 24、macOS/Node 22、Windows/Node 22のすべてで成功した。独立したレビューが正確な公開HEAD/treeを対象に行われ、P0=0、P1=0、P2=0、APPROVE、SAFE_TO_RELEASE=YESという結果を返している。
GitHubの境界はすでに公開済みで、未認証の読み取りでもリポジトリ本体、MITのLICENSE、v0.1.0タグに紐づくスキーマまで確認できる。
2026年9月30日、npm側の境界も閉じた。レジストリから@netsujo/agent-role-contracts@0.1.0を取得し、配布されたtarballのSHA-256が、GitHubリリース資産のSHA-256(12c07906fd8016f627ebd063248fbe78553bc9d64696e3578911e859f10c31a8)と一致することを確認した。クリーンな環境へnpm install @netsujo/agent-role-contracts@0.1.0でインストールし、validate・explain・handoffのいずれも、リポジトリ直下で実行したときと同じ結果を返した。
残っていたnpmの空白が埋まったことで、この記事が示す挙動は、GitHub上のソースだけでなく、実際にインストールして手元で再現できる状態になった。
この記事の著者

飯田 友広
代表取締役
Netsujo株式会社 代表取締役。京都発のWeb3・AI実装スタートアップを2023年6月に創業。Webサイトを営業基盤として捉え、経営・営業・検索・生成AI・コンバージョン・計測を横断して課題と改善優先順位を整理する「Netsujo SIGNAL」を設計・運営。さらに、ChatGPT・Codex・Claude Codeを状態再構築、競合回避、独立QC、Exact-head検証、停止、復旧まで含む制御ループで運用する社内AI開発基盤「Netsujo Agent OS」を設計・実運転。Netsujoとして京都ビッグデータ活用プラットフォームに参画(小規模企業会員(ベンチャー))し、同プラットフォーム発のワーキンググループ「Chain Up KYOTO」にも参画(2026年3月10日〜)。IVS2026サイドイベント「なぜ京都でWeb3.0ビジネスなのか」はNetsujoとして京都府庁旧議場で主催・企画・登壇・運営(2026年7月2日/京都府 総合政策環境部 デジタル政策推進課は共催)。京都美術工芸大学・龍谷大学での講義に加え、京都高度技術研究所(ASTEM)、旅館業界、就労支援施設、Open Source Conference等で登壇実績。ITコミュニティ「みやこでIT」(connpassメンバー639名・イベント176件・2019年2月から運営)運営。NPO法人NEMTUS理事、BAR KRYPTO運営。Netsujoはソーシャル企業認証制度「S認証」の認証企業(2026年2月認証・2026年4月公表)。技術領域はWeb3/ブロックチェーン/DID/NFT/生成AI/コミュニティ運営。
プロフィールを見るこの記事が向いている方
エージェント実行の手前に宣言チェックを置くかどうかを検討しているプラットフォーム担当者
PASSと実行許可・レビュー独立性・マージ権限を混同せずに運用設計したいITエンジニア
オープンソースの権限宣言チェッカーを自社のAgent Harnessへ組み込みたい開発リード
— 壁打ち相談
読者のよくある相談
記事を読んだ後に「自分の状況だとどう判断すべきか」を整理するための壁打ち相談を受け付けています。下記のような相談例が当てはまる方は、お気軽にご連絡ください。
Q. このチェッカーがPASSを返せば、そのままエージェントを実行してよいのか
PASSは宣言の整合性だけを保証します。実行許可、レビューの独立性、マージ・デプロイ権限は別の仕組みで確認します。
Q. validateとexplainとhandoffで、検査される範囲はどう違うのか
入力するファイルの数で決まります。引き継ぎの整合性はhandoffに文書を渡したときしか検査されません。
Q. 終了コードが1と2のときで、自動化の扱いをどう変えればよいか
1は宣言の書き直し、2はコマンドや入力ファイルの確認に振り分けます。どちらも実行を通しません。
上記いずれかが該当する場合、初回30分の壁打ち相談で論点整理に対応します。記事に書ききれない個別事情を踏まえた判断材料が必要な段階こそ、壁打ちが活きやすいフェーズです。
AI導入・PoC・業務実装のご相談
宣言チェックとレビュー体制を、運用設計から決める
どこまでを機械的な宣言チェックへ任せ、どこから人間のレビューと承認を残すか。構想段階でのご相談も可能です。