例とチュートリアル
Task Managerの例の完全ウォークスルー — 1文の説明からVDMJでチェックされた仕様、ランタイム契約エンフォースメント付きのTypeScriptコードまで。
Task Manager — 完全ワークフロー例
この例は統合ワークフローで構築し、VDMJチェックと一部POのSMT検証を実施。完全なソースコードはexamples/task-manager/で入手可能。 examples/task-manager/
38
生成された証明責務
23 / 23
スモークテスト成功
13
ランタイム契約チェック
定義 — VDM-SL仕様
タスクマネージャーはID、タイトル、説明、ステータス(Todo / InProgress / Done)、優先度(Low / Medium / High)、オプションの担当者を持つタスクを管理。主要ビジネスルール: タスクがDoneになると、TodoやInProgressに戻ることはできない。
module TaskManager definitions types TaskId = nat1; Priority = <Low> | <Medium> | <High>; Status = <Todo> | <InProgress> | <Done>; Task :: id : TaskId title : seq1 of char desc : seq of char status : Status priority : Priority assignee : [seq1 of char] inv t == len t.title <= 100 and len t.desc <= 500; TaskBoard = map TaskId to Task inv board == forall id in set dom board & board(id).id = id; functions ValidTransition: Status * Status -> bool ValidTransition(fromSt, toSt) == if fromSt = toSt then true else if fromSt = <Done> then false else true; operations CreateTask: seq1 of char * seq of char * Priority * [seq1 of char] ==> TaskId CreateTask(title, desc, priority, assignee) == ... pre len title <= 100 and len desc <= 500 post RESULT in set dom board and board(RESULT).status = <Todo>; ChangeStatus: TaskId * Status ==> () ChangeStatus(taskId, newStatus) == ... pre taskId in set dom board and ValidTransition(board(taskId).status, newStatus) post board(taskId).status = newStatus; DeleteTask: TaskId ==> () DeleteTask(taskId) == ... pre taskId in set dom board post taskId not in set dom board and card dom board = card dom board~ - 1; end TaskManager
主要な契約: TaskのinvがTitle/Descの文字数制限を強制。ChangeStatusのpreが有効な遷移のみ許可。DeleteTaskのpostが確実に1件のみ削除されることを保証。
検証 — VDMJの結果
✅ Parsed 1 module. No syntax errors ✅ Type checked 1 module. No type errors 📋 Generated 38 proof obligations Key POs: PO 8 — State init obligation: initial state satisfies invariant PO 22 — CreateTask postcondition: RESULT is in dom board with status <Todo> PO 27 — ChangeStatus postcondition: status updated, title preserved PO 36 — DeleteTask postcondition: taskId removed, board size decreased by 1
38件のPOが自動生成。型制約、サブタイプ制約、状態不変条件の保持、操作の事後条件の正しさをカバー。各POはClaudeにより平易な言語で解説されました。
証明 — SMT検証
3つの代表的POをSMT-LIBに変換して検証:
PO 8 (state init): ✅ Proved — empty board satisfies invariant PO 27 (ChangeStatus post): ✅ Proved — status updated, title preserved PO 36 (DeleteTask post): ✅ Proved — taskId removed, size decreased
生成 — TypeScriptコード
VDM-SL仕様はランタイム契約チェック付きTypeScriptにコンパイル。生成されたchangeStatusメソッド:
changeStatus(taskId: TaskId, newStatus: Status): void { // Pre-conditions (from VDM-SL) checkPre(this.board.has(taskId), `taskId ${taskId} not in dom board`); checkPre(validTransition(oldTask.status, newStatus), `Invalid transition: ${oldTask.status} → ${newStatus}`); const oldTitle = oldTask.title; const updated = mkTask(oldTask.id, oldTask.title, oldTask.desc, newStatus, oldTask.priority, oldTask.assignee); this.board.set(taskId, updated); // Post-conditions (from VDM-SL) checkPost(this.board.get(taskId)!.status === newStatus, `status must be ${newStatus}`); checkPost(this.board.get(taskId)!.title === oldTitle, `title must be preserved`); this.checkStateInvariant(); }
VDM-SL仕様のpre、post、invがランタイムのcheckPre/checkPost/checkInv呼び出しになります。違反するとContractErrorが正確な違反ルールと共にスローされます。
テスト — スモークテスト結果
=== TaskManager: Integrated Workflow Smoke Test === --- 1. Task Creation --- ✓ CreateTask: 'Design API' (High, Alice) ✓ CreateTask: 'Write Tests' (Medium, Bob) ✓ CreateTask: empty title rejected ✓ CreateTask: title > 100 chars rejected ✓ CreateTask: desc > 500 chars rejected --- 2. Status Transitions --- ✓ ChangeStatus: Todo → InProgress ✓ ChangeStatus: InProgress → Done ✓ ChangeStatus: Done → InProgress rejected ✓ ChangeStatus: Done → Todo rejected ✓ ChangeStatus: Todo → Todo (no-op) --- 3. Update & Delete --- ✓ UpdateTask: title & priority changed, status preserved ✓ DeleteTask: board size decreased by 1 ✓ DeleteTask: already deleted taskId rejected --- 5. Board Summary --- ✓ GetSummary: counts match board size --- 7. Invariant Enforcement --- ✓ mkTask: TaskId=0 (nat1) rejected ✓ mkTask: empty title (seq1 of char) rejected === Results: 23 passed, 0 failed ===
全23テスト成功。有効な入力は正常に処理され、無効な入力(空のタイトル、禁止された遷移、存在しないID)は生成された契約チェックにより明確なエラーメッセージと共に検出されます。v2.0.0のgenerate-testsスキルでは、仕様と設計文書から本格的なVitest/Jest契約テストスイート(型不変条件・事前事後条件・状態遷移・境界値テスト)も生成できます。
契約パターン
プラグインには一般的なエージェントアーキテクチャ用に7つの組み込み契約テンプレートが含まれます(v2.0.0でPhase 2設計文書テンプレートとハイブリッド判定エージェントを追加)。新しいエージェント定義時の出発点として使用。
変換エージェント
ステートレス入力→出力変換。例: テキストを言語間で変換する翻訳エージェント。
CRUDエージェント
永続状態を持つCreate/Read/Update/Delete。例: 上記のTask Manager。
パイプラインエージェント
順序データ処理ステージ。例: データを抽出、変換、ロードするETLエージェント。
メディエータエージェント
複数サブエージェントを調整。例: 在庫、決済、配送を調整する注文処理エージェント。
バリデーションエージェント
入力データを複合制約で検証し、正確なエラーを報告。例: 複合制約チェックと構造化エラーレポート。
設計文書テンプレート(v2.0.0)
Phase 2設計文書(PROTOCOL.md、API-SIGNATURES.md)を生成: メッセージ型レジストリ、ペイロード構造、状態遷移マトリクス、APIシグネチャ。
ハイブリッド判定エージェント(v2.0.0)
スコアベースの複合判定: スコア計算、しきい値比較、判定ロジック。