AI-DLC Workflow V2のセンサー: 承認ゲートの手前で動く自動検証
eslintやtscはCIで動かしている。でもそれ、成果物のレビュー前にも自動で走ってほしくないですか? しかもソースタグの漏れチェックや見出し構造の検証も同じ仕組みで。V2のセンサーは、承認ゲートの手前で「機械的にチェックできること」を自動検証し、結果を監査証跡に残す仕組みです。シリーズ第13回。
Series: AI-DLC Workflow V2の解説 (31 articles)
- …
- 13AI-DLC Workflow V2のセンサー: 承認ゲートの手前で動く自動検証 This article
1. なぜ機械検証が必要なのか
では、センサーが解決する課題から見ていきましょう。
V2では各ステージの成果物が承認ゲートを通過して次のステージに進みます。この承認ゲートで人間が「内容として正しいか」「方向性は合っているか」を判断する。これがV2の品質保証の基盤です。
ここで重要なのは、承認ゲートは「判断」に向いているという点です。「このアーキテクチャ案は妥当か」「このユーザーストーリーの優先順位は合っているか」。こうした問いには人間の経験や文脈理解が必要です。
一方で、こういった確認はどうでしょうか。
- この主張にソースタグが付いているか
- 必要なH2見出しが揃っているか
- 上流ステージの成果物を参照しているか
- 生成されたコードにlintエラーがないか
- 型エラーが残っていないか
これらは人間が目視でチェックする必要がない項目です。パターンが明確で、Yes/Noで判定でき、見落としは注意力の問題にすぎません。人間がチェックリストを目視確認する作業は、本来の「判断」を妨げるノイズになります。
V2の設計原則
V2のSpecificationでは、各ステージが「生成仕様」「検証仕様」「学習仕様」の3区画を持つと定義しています(Three-Compartment Construct)。センサーはこの「検証仕様」の実装にあたります。
検証には2つの種類があります。
| 種類 | 判定者 | 特性 |
|---|---|---|
| 推論的検証 | レビューアエージェント(LLM) | 「この設計は要件を満たしているか」を判断する。文脈理解が必要 |
| 計算的検証 | センサー(プログラム) | 「このタグは存在するか」を判定する。結果が一意に確定する |
センサーは後者です。LLMの解釈に依存せず、決定論的にYes/Noを返します。
もうひとつ重要な点があります。センサーの位置づけはadvisory(助言)です。ゲートをブロックするのではなく、人間の判断材料を提供します。センサーが失敗しても承認は可能です。「lintエラーがある」と表示された上で、人間が「これは意図的だ」と判断すればApproveできます。
センサーの共通アーキテクチャ
V2には5つのセンサーが標準で同梱されています。構造を把握するために、共通する仕組みを整理しておきます。
マニフェスト形式
各センサーは
.kiro/sensors/aidlc-<id>.md というMarkdownファイルで定義されます。YAMLフロントマターが構造化された契約を、本文が動作説明を担います。1
2
3
4
5
6
7
8
9
10
id: required-sections
kind: deterministic
command: bun .kiro/tools/aidlc-sensor-required-sections.ts
default_severity: advisory
description: Checks that stage output contains the required H2 headings
category: document-shape
matches: "**/{aidlc-docs,intents}/**"
timeout_seconds: 5
主要フィールドの意味はこうです。
id— センサーの識別子。ステージ側から参照される名前kind—deterministicのみ。プログラムで確定する検証であることを宣言command— 実行コマンド。TypeScriptで実装され、bunで実行されるdefault_severity—advisory。助言であり、ブロッカーではないmatches— 発火対象のファイルパターン(glob形式)timeout_seconds— タイムアウト。5秒(成果物系)〜60秒(型検査)
発火タイミング
成果物がファイルに書き込まれるたびに、PostToolUseフックがセンサーを自動発火します。人間が手動で実行する必要はありません。
出力
結果は
SENSOR_PASSED または SENSOR_FAILED としてaudit logに記録されます。失敗時は詳細ファイルが .aidlc-sensors/<stage-slug>/ ディレクトリに生成され、何を修正すべきかの手がかりになります。2. Intent Capture(ステージ1.1 Intent Capture & Framing)を追体験する
ここからは実際のステージでセンサーがどう動くかを見ていきます。まず、Ideationフェーズの最初のステージであるステージ1.1 Intent Capture & Framingです。
このステージには3つのセンサーが紐付いています。
claim-sources(根拠追跡センサー)
何を解決するのか
Intent Captureでは、プロジェクトの意図や前提を文書化します。ここで「セキュリティ要件が高い」と書いたとします。読み手が「その根拠は?」と聞いた時、答えられるでしょうか。
claim-sourcesセンサーは、成果物内の主張ブロックにソースタグが付いているかを検証します。
ソースタグの種類
| タグ | 意味 | 例 |
|---|---|---|
[desc] | ユーザーが最初に入力したタスク記述から | プロジェクトの目的に関する記述 |
[scope] | ワークフローで選択されたスコープ情報から | 初期スコープシグナルの記述のみ |
[Q<n>] | 質問への回答から(n番目の質問) | ユーザーとの対話で確認した事実 |
[memory:<id>] | active spaceのルールファイルから | org.md/team.md/project.mdの引用 |
[assumption] | 明示的な前提として | Assumptions & Open Questionsセクション内のみ |
検証の境界
ここで重要なのは、claim-sourcesが「何を検証しないか」です。このセンサーは「タグが存在するか」「タグが正しいファイルの正しいエントリに解決するか」だけを検証します。「引用されたソースが主張を実際に支持しているか」は検証しません。それはレビューアエージェントの仕事です。
機械でできることと、判断が必要なことの境界がここにあります。
失敗例
1
2
3
# プロジェクト概要
このシステムはセキュリティ要件が高い。 ← ソースタグなしこの記述にはタグがないため、
SENSOR_FAILED が発火します。修正後はこうなります。1
2
3
# プロジェクト概要
このシステムはセキュリティ要件が高い。[Q3] ← 質問3への回答が根拠required-sections(セクション構造センサー)
何を解決するのか
成果物に必要な見出しが揃っているかを検証します。デフォルトではH2見出しが2つ以上あるかという汎用チェックです。
テンプレートオーバーライド
チームが
aidlc/spaces/<space>/memory/templates/<artifact>.md にテンプレートファイルを配置すると、そのテンプレートのH2見出しセットが期待値になります。テンプレートは「エージェントが埋めるスケルトン」と「センサーがチェックする形状」を兼ねるため、作る形と確認する形が一致します。失敗例
intent-statement.mdにテンプレートが設定されていて、テンプレートに
## Assumptions & Open Questions が含まれている場合、その見出しがなければ SENSOR_FAILED になります。upstream-coverage(上流参照センサー)
何を解決するのか
各ステージはフロントマターの
consumes: フィールドで「どの上流成果物を入力として使うか」を宣言しています。upstream-coverageは、その宣言された上流成果物への参照が成果物内に実際に存在するかを検証します。参照として認識される形式
- スラグ単独トークン(例:
requirements。ただしnfr-requirementsの中に埋まっている場合は不可) - Wikilink形式(
[[requirements]]) - バッククォートファイル名(
`requirements.md`) - ディレクトリパス(
requirements-analysis/のようなパスセグメント)
Intent Captureでの動作
ステージ1.1 Intent Capture & Framingは
consumes: [] です。つまり上流に依存するものがない最初のステージなので、upstream-coverageは自動的にパスします。このセンサーが真価を発揮するのは後続ステージからです。3. Code Generation(ステージ3.5 Code Generation)を追体験する
次に、Constructionフェーズのステージ3.5 Code Generationを見ていきます。ここではコードを対象にした2つのセンサーが動きます。
linter(コード品質センサー)
何を解決するのか
生成されたコードがプロジェクトのlintルールに違反していないかを検証します。
動作の仕組み
プロジェクトに設定されたlinter(デフォルトはeslint)をラップして実行します。対象は
*.ts および *.js ファイルです。コードファイルが書き込まれるたびに発火し、構造化された出力を返します。1
2
3
4
5
6
7
8
9
10
11
{
"pass": false,
"violations": [
{
"file": "src/auth/middleware.ts",
"line": 42,
"rule": "no-unused-vars",
"message": "'token' is defined but never used"
}
]
}ファイル名、行番号、ルール名、メッセージが明確に示されるため、修正箇所が特定しやすくなっています。
type-check(型検査センサー)
何を解決するのか
型エラーが残ったまま承認ゲートに到達することを防ぎます。
動作の仕組み
プロジェクトに設定された型チェッカー(デフォルトはtsc)をラップして実行します。対象は
*.ts および *.tsx ファイルです。1
2
3
4
5
6
7
8
9
10
11
{
"pass": false,
"errors": [
{
"file": "src/auth/types.ts",
"line": 15,
"column": 3,
"message": "Type 'string' is not assignable to type 'AuthToken'"
}
]
}他の言語(Python、Go、Rust等)のlinterや型チェッカーを使いたい場合は、カスタムセンサーとして追加できます。
成果物センサーとコードセンサーの対比
ここまでで見た5つのセンサーを整理します。
| 観点 | 成果物センサー(claim-sources, required-sections, upstream-coverage) | コードセンサー(linter, type-check) |
|---|---|---|
| 対象 | Markdown成果物 | ソースコードファイル |
| 発火パターン | **/{aidlc-docs,intents}/** | **/*.{ts,js} / **/*.{ts,tsx} |
| カテゴリ | document-provenance / document-shape | code-quality |
| タイムアウト | 5秒 | 30〜60秒 |
| 多言語対応 | N/A(Markdownのみ) | eslint/tsc標準。他言語はカスタムセンサーで追加可能 |
成果物センサーは高速で軽量、コードセンサーは外部ツールを呼び出すため時間がかかる。この差がタイムアウト設定に反映されています。
「普通にlintを走らせる」のと何が違うのか
ここで疑問に思った方もいるかもしれません。「eslintやtscなんて、CIで普通に走らせてるけど?」と。確かにツール自体は同じです。では何が違うのか、整理しておきましょう。
| 観点 | 手動 / CI実行 | V2センサーとしての実行 |
|---|---|---|
| 発火タイミング | 人間がコマンドを打つ、またはpush後にCI | ファイル書き込み時に即座に自動発火 |
| 結果の記録先 | ターミナル出力やCIログ | audit logにSENSOR_PASSED/FAILEDとして記録。監査証跡に残る |
| 承認ゲートとの連動 | なし(別プロセス) | 結果が承認ゲートの判断材料として人間に提示される |
| 管理インターフェース | ツールごとに設定ファイルが異なる | 統一されたマニフェスト形式で定義。成果物検証と同じ仕組みで管理 |
| ステージとの紐付け | なし(プロジェクト全体に適用) | ステージのフロントマターsensors:で、どのステージにどの検証を適用するかを制御 |
言い換えれば、センサーは「既存ツールをワークフローに組み込むアダプター」です。ツールの能力はそのまま活かしつつ、発火の自動化、結果の構造化記録、承認判断への接続、ステージ単位の適用制御を加えています。
4. センサー適用の全体マップ
ここまで個別のステージで見てきたセンサーを、全体像として俯瞰します。どのフェーズ・ステージにどのセンサーが適用されるかの対応表です。
| フェーズ | 対象ステージ | claim-sources | required-sections | upstream-coverage | linter | type-check |
|---|---|---|---|---|---|---|
| Initialization | 3ステージ(workspace-scaffold等) | — | — | — | — | — |
| Ideation | ステージ1.1 Intent Capture & Framing | ○ | ○ | ○ | — | — |
| Ideation | 残り6ステージ(Market Research等) | — | ○ | ○ | — | — |
| Inception | 9ステージ(Reverse Engineering等) | — | ○ | ○ | — | — |
| Construction | 5設計ステージ(Functional Design, Infrastructure Design, NFR Design, NFR Requirements, CI Pipeline) | — | ○ | ○ | ○ | ○ |
| Construction | ステージ3.5 Code Generation | — | — | — | ○ | ○ |
| Construction | ステージ3.6 Build and Test | — | ○ | ○ | — | ○ |
| Operation | 7ステージ(Deployment Pipeline等) | — | ○ | ○ | — | — |
パターンの読み取り方
この表から見えるパターンを整理します。
claim-sourcesはステージ1.1 Intent Capture & Framingのみ。根拠追跡が意味を持つのは「主張と根拠の対応付け」が求められるこのステージだけです。他のステージでは上流成果物への参照(upstream-coverage)がトレーサビリティを担保します。
required-sections + upstream-coverageはInitialization以外のほぼ全ステージに適用。構造チェックと上流参照チェックは成果物を生成するステージ共通の関心事です。
linter / type-checkはConstructionフェーズに集中。コードを生成・修正するステージにのみ適用されます。設計ステージでも適用されるのは、Markdownの中にコードサンプルが含まれるためです。
Initializationは対象外。ディレクトリ構造の作成や状態ファイルの初期化はエージェントが書く成果物ではないため、センサーは不要です。
ステージへの紐付け方
各ステージのフロントマターにある
sensors: リストがこの対応を定義しています。1
2
3
4
5
6
7
slug: code-generation
phase: construction
sensors:
- linter
- type-check
追加したければidをリストに加え、外したければリストから除く。紐付けはステージ側が持つため、マニフェスト自体を変更する必要はありません。
5. カスタムセンサーを作る
標準の5つでカバーできないプロジェクト固有の検証ルールがある場合、カスタムセンサーを作れます。
いつ必要になるか
例えば以下のような場面です。
- API設計にレート制限の記述が必ず含まれるべきプロジェクト
- セキュリティレビューで特定のパターン(hardcodedなシークレット等)を機械的に検出したい
- 社内コーディング規約でlinterがカバーしていないルールがある
3ステップで作る
Step 1: マニフェストを作成する
.kiro/sensors/aidlc-rate-limit-check.md を作ります。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
id: rate-limit-check
kind: deterministic
command: bun .kiro/tools/aidlc-sensor-rate-limit-check.ts
default_severity: advisory
description: Checks that API design documents include rate limiting specifications
category: document-shape
matches: "**/{aidlc-docs,intents}/**/api-*.md"
timeout_seconds: 5
# rate-limit-check sensor
API設計ドキュメントにレート制限の記述が含まれているかを検証します。
## 検証内容
- `## Rate Limiting` または `## レート制限` セクションの存在
- 具体的な数値(リクエスト数/秒、バースト制限)の記載
## Failure mode
セクションが存在しない、または数値が含まれない場合に SENSOR_FAILED を発火します。Step 2: コマンドを実装する
.kiro/tools/aidlc-sensor-rate-limit-check.ts を作成し、検証ロジックを実装します。入力として --output-path と --stage を受け取り、exit code 0(パス)または非0(失敗)を返します。Step 3: ステージに紐付ける
対象ステージのフロントマターに追加します。
1
2
3
4
sensors:
- required-sections
- upstream-coverage
- rate-limit-check # 追加これで、対象ステージで成果物が書き込まれるたびにカスタムセンサーが自動発火します。
学習ループからのセンサー提案
V2には学習ループという仕組みがあります。人間のフィードバックをプロジェクト固有のルールとして永続化する仕組みです。この中で「このチェックはセンサーにすべきだ」と判断された場合、マニフェストとステージ紐付けが自動提案されます(
SENSOR_PROPOSED イベント)。つまり、カスタムセンサーの作成は「人間が能動的に設計する」パスと「学習ループが提案する」パスの両方から起こりえます。検証ルールを使いながら育てていく設計です。
6. まとめ
この記事ではV2のセンサーの設計思想と動作を見てきました。
- センサーは計算的検証を担う仕組みです。LLMの判断に依存せず、決定論的にYes/Noを返します
- 承認ゲートの手前で自動発火し、人間の判断材料を提供します。位置づけはadvisory(助言)であり、ブロッカーではありません
- 5つの標準センサーがフレームワークに同梱されています。成果物の構造チェック(claim-sources, required-sections, upstream-coverage)とコード品質チェック(linter, type-check)の2カテゴリです
- プロジェクト固有の検証ルールはカスタムセンサーで追加できます。マニフェスト作成→コマンド実装→ステージ紐付けの3ステップです
- 検証ルールを育てることで、人間の介入が必要な領域を段階的に狭められます。学習ループからの自動提案もその一環です
センサーとレビューアエージェントは対になる存在です。機械で確定できることはセンサーが処理し、文脈理解や判断が必要なことはレビューアが担う。承認ゲートに到達する頃には、人間は「判断」だけに集中できる状態が整っています。
Series: AI-DLC Workflow V2の解説 (31 articles)
- …
- 13AI-DLC Workflow V2のセンサー: 承認ゲートの手前で動く自動検証 This article
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article