skills/define-contract/SKILL.md
形式的エージェント契約を定義し、VDM-SL仕様と設計文書(プロトコル仕様)を生成するスキル
npx skillsauth add kotaroyamame/formal-agent-contracts define-contractInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
形式的エージェント契約を段階的に定義し、VDM-SL(Vienna Development Method Specification Language)仕様と設計文書(PROTOCOL.md、API-SIGNATURES.md)を生成するスキルです。v0.2.0では Phase 1(ドメイン論理)の VDM-SL 仕様に加えて、Phase 2(プロトコル・API 仕様)の設計文書生成に対応し、複雑なマルチエージェントシステムに対応しています。
このスキルは以下のワークフローを実行します:
目的:対象エージェントの明確な責務定義
ユーザーに以下の情報を聞き出します:
HybridJudgeAgent, MessageValidator出力例:
エージェント:HybridJudgeAgent
責務:チケットの自動返信可否を判定し、処理方法(自動応答/オペレータ連携/オペレータのみ)を決定する
入力:Ticket型(ID、本文、顧客情報、優先度、複雑度スコア)
出力:Action型(<AutoReply> | <OperatorAndLLM> | <OperatorOnly>)
状態:ステートレス(判定時点の入力値のみに依存)
依存:MessageValidator(メッセージ検証)、ScoreCalculator(スコア計算)
目的:エージェントが扱う全データ型を形式化
以下の形式でデータ型を定義します:
-- 基本型
Score = nat1 -- 1から100までのスコア
Priority = <Low> | <Medium> | <High>
-- レコード型
Ticket ::
id : nat1
content : seq of char
priority : Priority
complexity_score : Score
各型について以下を明確にします:
ユーザーへの質問:
目的:マルチエージェント間の通信仕様を設計文書として形式化
このステップは複数のエージェント間で通信が存在する場合に適用します。ここで生成される成果物は PROTOCOL.md と API-SIGNATURES.md という設計ドキュメントであり、VDM-SL コードではありません。これらの文書はプロトコル実装エージェントと API 実装エージェントが直接参照します。
全てのメッセージ型を正規名として宣言。Markdown テーブル形式で記録:
| メッセージ型(正規名) | 送信元 | 受信先 | 同期/非同期 | 説明 |
|---|---|---|---|---|
| TicketCreate | User | Server | 同期 | ユーザーがチケットを作成 |
| TicketUpdate | User | Server | 同期 | ユーザーがチケットを更新 |
| EscalationRequest | User | Server | 同期 | ユーザーがエスカレーションをリクエスト |
| ReplyManual | Operator | Server | 同期 | オペレータが手動返信 |
| TicketCreated | Server | User | 非同期 | サーバーがチケット作成完了を通知 |
| AutoReply | Server | User | 非同期 | サーバーが自動返信を送信 |
| OperatorReply | Server | User | 非同期 | サーバーがオペレータからの返信を転送 |
定義時のチェックポイント:
各メッセージ型のペイロード(データ本体)をフィールド定義テーブルで記述:
| フィールド名 | 型 | 必須/省略可 | 説明 |
|---|---|---|---|
| content | string | 必須 | チケット本文 |
| customerId | int | 必須 | 顧客ID |
| priority | enum: Low | Medium | High | 必須 | 優先度 |
| attachments | string[] | 省略可 | 添付ファイルURL配列 |
| フィールド名 | 型 | 必須/省略可 | 説明 |
|---|---|---|---|
| ticketId | int | 必須 | チケットID |
| operatorId | int | 必須 | オペレータID |
| message | string | 必須 | 返信内容 |
| resolution | enum: Resolved | Pending | 必須 | 解決状態 |
マルチエージェント通信で参照される API 関数を 正確な署名 で宣言(API-SIGNATURES.md):
// MessageValidator API
interface MessageValidator {
validatePayload(msgType: string, payload: object): ValidationResult
// パラメータ順序: msgType, payload
// 戻り値: { isValid: bool, errors: string[] }
checkDirection(sender: string, msgType: string): boolean
// パラメータ順序: sender, msgType
}
// StateTransition API
interface StateTransition {
isValidTransition(currentStatus: string, newStatus: string): boolean
// パラメータ順序: currentStatus, newStatus
getValidTransitions(currentStatus: string): string[]
// パラメータ順序: currentStatus
// 戻り値: 遷移可能な状態の配列
}
重要:パラメータの名前・順序・型は実装エージェントが直接参照するため、一度決めたら変更不可。
プロトコルで管理される状態の遷移を Markdown 表で定義(VDM-SL ではなく):
| 現在の状態 | → Created | → Assigned | → InProgress | → Resolved | → Closed | |---|:---:|:---:|:---:|:---:|:---:| | Created | ✗ | ✓ | ✗ | ✗ | ✓ | | Assigned | ✗ | ✗ | ✓ | ✗ | ✓ | | InProgress | ✗ | ✗ | ✗ | ✓ | ✓ | | Resolved | ✗ | ✗ | ✗ | ✗ | ✓ | | Closed | ✗ | ✗ | ✗ | ✗ | ✗ |
各ペイロード型で、null を許容するフィールドを明示:
| メッセージ型 | Null 許容フィールド | デフォルト値 |
|---|---|---|
| TicketCreate | attachments | [] |
| ReplyManual | なし | — |
| AutoReply | operatorName | null |
プロトコル全体で使用する命名規約を統一宣言(一度だけ記述):
【命名規約】
- メッセージ型:PascalCase(例:TicketCreate、AutoReply)
- ペイロード型:メッセージ型 + Payload suffix(例:TicketCreatePayload)
- フィールド名:camelCase(例:ticketId、operatorId)
- 状態値:PascalCase(例:Created、InProgress)
- API 関数名:動詞 + 名詞、camelCase(例:validatePayload、isValidTransition)
- 列挙値:PascalCase(例:Low、Medium、High、Resolved、Pending)
設計文書(PROTOCOL.md、API-SIGNATURES.md)に上記全てが含まれていることを確認。
目的:エージェントの前提条件と後提条件を形式化
各エージェント操作について、以下の契約を定義します:
-- 関数シグネチャ
decide : Ticket -> Score -> Score -> Action
decide(ticket, t1, t2) == ???
-- 前提条件(precondition)
pre decide(ticket, t1, t2) ==
t1 > t2 and
ticket.complexity_score >= 0 and t1 <= 100 and t2 <= 100
-- 後提条件(postcondition)
post decide(ticket, t1, t2) ==
(let action = decide(ticket, t1, t2) in
(ticket.complexity_score > t1 => action = <OperatorOnly>) and
(t2 < ticket.complexity_score <= t1 => action = <OperatorAndLLM>) and
(ticket.complexity_score <= t2 => action = <AutoReply>)
)
ユーザーへの質問:
契約記述のチェックポイント:
目的:Phase 1(ドメイン論理)のVDM-SL仕様書を自動生成
重要:このステップでは、ステップ2で定義したデータ型と、ステップ3で定義した契約(前提条件・後提条件)のみを VDM-SL に変換します。ステップ2bで生成した設計文書(PROTOCOL.md、API-SIGNATURES.md)は VDM-SL に含めません。プロトコル仕様は別ドキュメントとして実装エージェントが直接参照します。
ユーザーが提供した情報を整形して、完全なVDM-SL仕様モジュールを生成します:
module HybridJudgeAgent
imports all from Prelude
exports all
definitions
-- ======== 型定義 (Phase 1: ドメイン論理) ========
Score = nat1
Threshold = nat1
-- 不変式付き型
Score inv s == s >= 1 and s <= 100
Threshold inv t == t >= 1 and t <= 100
Action = <AutoReply> | <OperatorAndLLM> | <OperatorOnly>
-- ======== メイン関数 ========
decide : Ticket -> Score -> Score -> Action
decide(ticket, t1, t2) ==
if ticket.complexity_score > t1
then <OperatorOnly>
elseif ticket.complexity_score > t2
then <OperatorAndLLM>
else <AutoReply>
pre decide(ticket, t1, t2) ==
t1 > t2 and
ticket.complexity_score >= 1 and ticket.complexity_score <= 100 and
t1 <= 100 and t2 <= 100
post decide(ticket, t1, t2) ==
(let action = decide(ticket, t1, t2) in
(ticket.complexity_score > t1 => action = <OperatorOnly>) and
(t2 < ticket.complexity_score <= t1 => action = <OperatorAndLLM>) and
(ticket.complexity_score <= t2 => action = <AutoReply>)
)
end HybridJudgeAgent
生成される出力物:
目的:生成された仕様の正確性を確認
以下の観点からレビューをガイドします:
型整合性
不変式の妥当性
契約の実現可能性
プロトコル完全性(v0.2.0)
名前付け規約の一貫性
レビューの実施: ユーザーに対して、以下の質問を提示します:
目的:VDM-SL仕様と設計文書から自動的にテストを生成
仕様レビューが完了したら、以下の提案をします:
提案:この仕様からユニットテストを自動生成しますか?
generate-tests スキルを実行すると、以下のテストが自動生成されます:
【Phase 1: ドメイン論理テスト】(VDM-SL仕様に基づく)
1. 型不変式テスト
- Score型の値域チェック(1-100)
- Threshold型の値域チェック
- 無効な型の構築防止
2. 前提条件テスト
- t1 > t2の検証
- 複雑度スコアの有効範囲チェック
- 無効な入力でのエラー処理
3. 後提条件テスト
- 各判定ロジック(複雑度スコア > t1 => <OperatorOnly>等)
- エッジケース(複雑度スコア == t1, == t2)
- 全アクション型の網羅
【Phase 2: プロトコル・API テスト】(設計文書に基づく)
4. メッセージペイロード検証テスト
- 各ペイロード型のフィールド妥当性チェック
- null フィールドの処理検証
- 必須フィールドの存在確認
5. 状態遷移テスト
- 状態遷移マトリクスの有効性検証
- 無効な遷移の拒否確認
- 全状態・遷移パターンの網羅
6. API シグネチャ実装テスト
- パラメータ順序の正確性
- 戻り値型の一致確認
- API 関数呼び出しの互換性
実行:[generate-tests スキルを実行]
このスキルで使用される標準テンプレート:
参照: contract-templates.md#pattern1
参照: contract-templates.md#pattern2
参照: contract-templates.md#pattern3
参照: contract-templates.md#pattern4
参照: contract-templates.md#pattern5
参照: contract-templates.md#pattern6
参照: contract-templates.md#pattern7
ステップ1: エージェントロール抽出
↓
ステップ2: データ型定義(Phase 1: ドメイン論理)
↓
ステップ2b: 設計文書生成(PROTOCOL.md, API-SIGNATURES.md)(Phase 2: プロトコル・API仕様)
↓
ステップ3: 契約定義(前提条件・後提条件)
↓
ステップ4: VDM-SL仕様生成(Phase 1)
↓
ステップ5: 仕様・設計文書レビュー
↓
ステップ6: 契約テスト生成の提案(Phase 1 + Phase 2)
↓
[完了 または generate-tests スキルへ移行]
ユーザー入力:
- エージェント名:ScoreCalculator
- 責務:チケットの複雑度スコアを計算する
- 入力:Ticket型
- 出力:Score型(1-100)
生成される仕様:
module ScoreCalculator
Score = nat1
inv s == s >= 1 and s <= 100
calculateScore : Ticket -> Score
calculateScore(ticket) == ???
post calculateScore(ticket) ==
let score = calculateScore(ticket) in
score >= 1 and score <= 100
end ScoreCalculator
ユーザー入力:
- エージェント1:HybridJudgeAgent(判定)
- エージェント2:MessageValidator(検証)
- 間の通信:メッセージベースのプロトコル
生成される設計文書(ステップ2b):
【PROTOCOL.md】
## メッセージ型レジストリ
| メッセージ型 | 送信元 | 受信先 | 同期/非同期 |
|---|---|---|---|
| TicketCreate | User | Server | 同期 |
| TicketUpdate | User | Server | 同期 |
| AutoReply | Server | User | 非同期 |
## ペイロード構造 (TicketCreate)
| フィールド | 型 | 必須 |
|---|---|---|
| content | string | yes |
| priority | enum | yes |
| attachments | string[] | no |
## 状態遷移マトリクス
| 現在 | Created | Assigned | InProgress | Resolved | Closed |
|---|:---:|:---:|:---:|:---:|:---:|
| Created | ✗ | ✓ | ✗ | ✗ | ✓ |
| ...
【API-SIGNATURES.md】
interface MessageValidator {
validatePayload(msgType: string, payload: object): ValidationResult
checkDirection(sender: string, msgType: string): boolean
}
interface StateTransition {
isValidTransition(currentStatus: string, newStatus: string): boolean
}
生成される VDM-SL 仕様(ステップ4、Phase 1):
module HybridSystem
-- ステップ3で定義した契約(ドメイン論理)
decide : Ticket -> Score -> Score -> Action
pre/post ...
-- 注意:メッセージ型・状態遷移は VDM-SL に含めない
-- それらは PROTOCOL.md で定義されている
end HybridSystem
A: VDM-SLの型参照が循環していないか確認してください。循環参照がある場合は、型の定義順序を変更するか、前方宣言を使用してください。
A: 前提条件の目的を再考してください。エージェントが入力を検証する責務を持つ場合、前提条件は「検証済み」という仮定として記述するべきです。一方、呼び出し元が責務を持つ場合は前提条件で強く制約してください。
A: メッセージ型を細分化することを検討してください。例えば UserMsgType をさらに UserInMsgType と UserOutMsgType に分割できます。
A: 後提条件は単一の関数の動作のみを記述するべきです。複数の関数の相互作用は、別途の統合テストで検証してください。
../generate-tests/SKILL.md../verify-spec/SKILL.md最終更新: 2026-04-12
バージョン: 0.2.0
メンテナ: Formal Agent Contracts チーム
testing
VDM-SL仕様の型チェック、構文検証、証明責務生成を実行するスキル
testing
Convert VDM-SL proof obligations (POs) to SMT-LIB and verify them with the Z3 solver. Triggered by "prove POs", "verify with SMT", "check with Z3", "auto-verify proof obligations", "prove the spec is correct", or "find counterexamples". Also responds to Japanese: 「POを証明して」「SMTで検証して」「Z3で確認して」等。 Used as the next step after PO generation with verify-spec, or for end-to-end PO generation + SMT verification.
development
Orchestrate the full reverse engineering pipeline: Extract provisional spec from existing code, refine through dialogue to uncover the true spec, then reconcile code with the confirmed spec. Optionally connects to the forward pipeline (verify → prove → generate → test). Triggered by: "reverse workflow", "extract and refine spec from code", "formalize existing code", "reverse engineer the specification", 「リバースワークフローで」「既存コードから仕様を起こして」「コードの仕様を明確にしたい」 「このプロジェクトを形式仕様で整理したい」「既存コードをリバースエンジニアリングして」
testing
Refine a provisional VDM-SL specification through dialogue with the user, uncovering the true specification that exists in the user's mind. The provisional spec (from extract-spec) serves as a scaffold for questions. Triggered by: "refine the spec", "review the provisional spec", 「仕様を磨きたい」「仮仕様をレビューして」「コードの意図を確認したい」「仕様を確認して」