
AI-DLC v1/v2 の逆解析成果物を構造比較してみた
はじめに
前回記事は、AI-DLC v2 の逆解析を「使ってみた」体験記でした。
本記事は v1/v2 × Sonnet/Opus の4パターンで逆解析し、構造を比較しました。v2 では逆解析の中核ファイル名が application-design と同名で揃い、後続の設計フェーズに渡すことを意図した構造になっています。条件付きファイルの実生成有無は scope・題材・モデルによって変動します。実際に改善設計の入力として活用できるかは続編で検証します。
AI-DLC とは
AI-DLC(AI-Driven Development Life Cycle)は、AI がソフトウェア開発ライフサイクルを駆動するフレームワークです。v2 は本記事の検証時点ではベータ版で、Kiro 専用(IDE / CLI)として利用できます。本記事では、v1 の既存ワークフローと v2 の Kiro 向けワークフローを比較します。詳細は AWS 公式ブログ を参照してください。
題材
before.yaml(CloudFormation 4リソース・約50行の Echo Lambda)を逆解析の対象としました。リクエストのヘッダーとソース IP をそのまま返す関数を、認証なしで公開しています。続編ではこの公開エンドポイントを、Function URL の認証設定変更と CloudFront OAC の組み合わせで保護する改善を逆解析成果物を起点に実施予定です。
before.yaml(解析対象ソース全文)
AWSTemplateFormatVersion: '2010-09-09'
Description: Public Lambda Function URL - Echo headers and source IP (intentionally unprotected)
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${AWS::StackName}-lambda-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
EchoFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub '${AWS::StackName}-echo'
Runtime: python3.13
Handler: index.handler
Role: !GetAtt LambdaRole.Arn
Code:
ZipFile: |
import json
def handler(event, context):
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({
"sourceIp": event["requestContext"]["http"]["sourceIp"],
"headers": event["headers"]
}, indent=2)
}
FunctionUrl:
Type: AWS::Lambda::Url
Properties:
AuthType: NONE
TargetFunctionArn: !GetAtt EchoFunction.Arn
FunctionUrlPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunctionUrl
FunctionName: !GetAtt EchoFunction.Arn
Principal: '*'
FunctionUrlAuthType: NONE
Outputs:
FunctionUrlEndpoint:
Description: Public Function URL endpoint
Value: !GetAtt FunctionUrl.FunctionUrl
v1 vs v2: 保存形式の違い
各パターンは別ディレクトリに複製した同一リポジトリで実行し、生成物を個別に保存して比較しました。まず保存場所・階層を見ます。ファイル名と設計フォーマットの対応は次章で扱います。
保存場所・階層
| Run | パス |
|---|---|
| v1(Opus/Sonnet 共通) | aidlc-docs/inception/reverse-engineering/ |
| v2-opus | aidlc-docs/intent-001-reverse-engineering/inception/reverse-engineering/echo-function-url/ |
| v2-sonnet | aidlc-docs/intent-001-cfn-echo-lambda-re/inception/reverse-engineering/cfn-echo-lambda/ |
v1 は inception/reverse-engineering/ 直下に成果物が並ぶフラット構造です。v2 では intent 名と repo 名の階層が加わり、複数の改善意図やリポジトリを分離して管理できる構造になっています。v2 の規約上の正規パスは org-ai-kb/ 配下ですが、本 run ではいずれも aidlc-docs/ 直下に生成されました。本記事で比較しているのはこの実行結果です。
v2 のファイル名と設計フォーマットの同名性
v2 の逆解析スキル定義(aidlc-workflows commit 47b4edcf、skills/aidlc-reverse-engineering/SKILL.md)には downstream consumption について以下の記載があります。
"Output mirrors the Application Design format so downstream stages can consume RE artifacts identically."
application-design と逆解析のファイル名対応
母数の定義は、v2 逆解析スキルが application-design 互換として定義する中核ファイル名 9件です。実行過程を記録する補助ファイル(intent / workflow / state / audit / bootstrap)は母数に含めません。
application-design と逆解析の出力は同名です。
必須ファイル:
- components.md
- component-methods.md
- component-dependencies.md
- services.md
- cross-cutting.md
- api-contracts.md
条件付きファイル(scope・題材・モデルによって生成有無が変動):
- data-models.md
- event-catalog.md
- external-dependencies.md
下流活用の設計意図
逆解析スキル定義には Downstream Consumption の設計も明記されています。
"If both exist, Application Design takes precedence. RE artifacts serve as the baseline that Application Design refines."
v1 の architecture.md は設計フェーズのファイル名と無関係な独自名であり、今回確認した v1 の定義・生成物からはファイル名で下流と連携する仕組みが確認できませんでした。v2 なら application-design の入力フォーマットと同名で一致するため、改善設計が同名ファイルの override として表現される設計意図が読み取れます。
代表ペアの中身比較
ペア1: v1 architecture.md ↔ v2 components.md + component-dependencies.md
v1: architecture.md(EchoFunction 部分の散文抜粋)
### EchoFunction
- **Purpose**: HTTPリクエストの送信元IPとヘッダーをJSONで返すLambda関数
- **Responsibilities**: イベントからsourceIpとheadersを抽出してJSONレスポンスを生成
- **Dependencies**: LambdaRole(IAM)、FunctionUrl(トリガー)
- **Type**: Application
v2-sonnet: components.md(EchoFunction の属性テーブル)
## EchoFunction
| Attribute | Value |
|---|---|
| Purpose | HTTP リクエストのヘッダーとソース IP をエコーバックする Lambda 関数 |
| Type | AWS::Lambda::Function |
| Source | before.yaml `Resources.EchoFunction` |
| Responsibilities | Function URL 経由で受信した HTTP リクエストを処理し、リクエストコンテキストから sourceIp とヘッダーを抽出して JSON レスポンスとして返却。 |
| State | Stateless (純粋な request-response) |
| Ownership | アプリケーション層 |
v2-sonnet: component-dependencies.md(Dependency Matrix 表)
| From | To | Type | Communication Pattern | Source |
|---|---|---|---|---|
| EchoFunction | LambdaRole | IAM role assumption | `Role: !GetAtt LambdaRole.Arn` | before.yaml EchoFunction.Properties.Role |
| FunctionUrl | EchoFunction | Target binding | `TargetFunctionArn: !GetAtt EchoFunction.Arn` | before.yaml FunctionUrl.Properties.TargetFunctionArn |
| FunctionUrlPermission | EchoFunction | Permission grant | `FunctionName: !GetAtt EchoFunction.Arn` | before.yaml FunctionUrlPermission.Properties.FunctionName |
v1 では architecture.md 内にコンポーネント定義と依存関係が記述されていますが、v2 ではコンポーネント定義と依存関係が分離され、テーブル形式でソース参照まで明記されています。
ペア2: v1 api-documentation.md ↔ v2 api-contracts.md
v1: api-documentation.md(Echo Endpoint + Internal API 部分)
## REST APIs
### Echo Endpoint
- **Method**: 任意(GET / POST / PUT 等、Lambda Function URLはメソッドを制限しない)
- **Path**: `/`(Function URLのルートパス)
- **Auth**: なし(`AuthType: NONE`、`Principal: *`)
**Response** (HTTP 200):
{
"sourceIp": "203.0.113.1",
"headers": { ... }
}
## Internal APIs
### handler(event, context)
- **Parameters**:
- `event["requestContext"]["http"]["sourceIp"]` - 送信元IPアドレス
- `event["headers"]` - HTTPリクエストヘッダー辞書
- **Return Types**: {"statusCode": 200, "headers": {...}, "body": str}
v2-sonnet: api-contracts.md(外部契約のみ、Error Cases テーブル付き)
## Echo Endpoint
| Attribute | Value |
|---|---|
| Endpoint | `{FunctionUrl}` (CloudFormation Output: FunctionUrlEndpoint) |
| Protocol | HTTPS (TLS enforced by Lambda Function URL) |
| Auth | None (AuthType: NONE) |
| Methods | ANY (Lambda Function URL accepts all HTTP methods) |
### Error Cases
| Condition | Behavior |
|---|---|
| Normal request | HTTP 200 + echo payload |
| Malformed event (missing requestContext) | HTTP 500 (Lambda runtime KeyError) |
| Lambda timeout | HTTP 500 (Lambda runtime) |
| Lambda throttle | HTTP 429 (Lambda service) |
v1 は外部 API と内部実装を1ファイルに混在させていますが、v2 では外部契約だけを切り出し、異常系のケースも構造化されています。
ペア3: v1/v2 code-quality-assessment.md(同名ファイル比較)
v1: code-quality-assessment.md(Anti-patterns 箇条書き部分)
### Anti-patterns
- **認証なし公開エンドポイント** (`FunctionUrl`, `FunctionUrlPermission`):
セキュリティリスク。意図的とはいえ本番環境では問題。
- **インラインLambdaコード**: `ZipFile` によるインライン埋め込みは
テスト・バージョン管理が困難。小規模コードには許容範囲だが、拡張性に欠ける。
- **エラーハンドリング欠如**: 予期しないイベント構造に対して脆弱。
v2-sonnet: code-quality-assessment.md(Anti-Patterns テーブル + Complexity Metrics テーブル)
## Anti-Patterns Observed
| Anti-Pattern | Evidence | Impact |
|---|---|---|
| No error handling | try/except なし | 予期しない入力で 500 エラー |
| No input validation | event 構造を無検証で参照 | KeyError リスク |
| No application logging | print/logging 呼び出しなし | デバッグ困難 |
| Inline code (not externalized) | ZipFile プロパティ使用 | テスト不可、バージョン管理困難 |
| No Function URL throttling | 組み込みの制御なし | DoS リスク |
## Complexity Metrics
| Metric | Value |
|---|---|
| Total lines (YAML) | ~49 |
| CloudFormation resources | 4 |
| Lambda code lines | 10 |
| Cyclomatic complexity | 1 (分岐なし) |
| External dependencies | 0 (stdlib only) |
同名ファイルでも、v1 は箇条書き、v2 は Evidence/Impact 付きテーブルと定量指標で構造化されています。
Sonnet vs Opus: 今回の run で見えた差分
今回の run では、v1 の出力差は小さく見えました。一方 v2 では、生成物の粒度や記録内容の差が v1 より目立ちました。ただし生成されたファイルの名前はどちらもスキル定義通りで一貫しています。
今回の v2-opus run では未宣言設定の列挙、行番号の参照、Output を含む !GetAtt 参照関係の記録が見られました。Sonnet でも構造比較に必要な成果物は得られましたが、Opus のほうが細かく拾い上げている印象です。
v2-opus: components.md(EchoFunction — 未宣言設定列挙+行番号参照)
## 2. EchoFunction (`AWS::Lambda::Function`)
- **Purpose:** Serverless HTTP handler that echoes the caller's source IP and request headers.
- **Responsibilities (from inline code `before.yaml:28–38`):**
- Returns HTTP 200 with `Content-Type: application/json`.
- Body is `json.dumps(...)` of { "sourceIp": ..., "headers": ... } with `indent=2`.
- **State/Config:**
- `FunctionName: !Sub '${AWS::StackName}-echo'`
- `Runtime: python3.13`
- `Handler: index.handler`
- `Role: !GetAtt LambdaRole.Arn`
- Code is inline (`Code.ZipFile`), single module, no external packages beyond stdlib `json`.
- No `MemorySize`, `Timeout`, `Environment`, `Architectures`, `Layers`, or VPC config declared
→ AWS defaults apply.
v2-opus: component-dependencies.md(Output行含む Dependency Matrix)
## Dependency Matrix
| From | To | Mechanism | Communication Pattern | Source |
|---|---|---|---|---|
| `EchoFunction` | `LambdaRole` | `Role: !GetAtt LambdaRole.Arn` | Deploy-time CFN reference; runtime assumed-role identity | `before.yaml:25` |
| `FunctionUrl` | `EchoFunction` | `TargetFunctionArn: !GetAtt EchoFunction.Arn` | Deploy-time CFN reference; runtime HTTPS → Lambda invoke | `before.yaml:44` |
| `FunctionUrlPermission` | `EchoFunction` | `FunctionName: !GetAtt EchoFunction.Arn` | Deploy-time CFN reference (resource-based policy) | `before.yaml:50` |
| `FunctionUrlEndpoint` (Output) | `FunctionUrl` | `Value: !GetAtt FunctionUrl.FunctionUrl` | Deploy-time CFN reference | `before.yaml:57` |
まとめ
v2 の変化は、逆解析結果が単なる説明文書ではなく、後続の設計フェーズが活用する前提の構造化フォーマットで保存されるようになった点です。この構造の違いが AI-DLC の改善フローで実際にどう効くかは、続編の記事で紹介したいと思います。
検証環境
| 項目 | 値 |
|---|---|
| OS | Fedora Asahi Remix 43 (aarch64) |
| Kiro CLI | v2.5.0 |
| AI-DLC v1 | GitHub awslabs/aidlc-workflows main branch(2026-05-28 取得) |
| AI-DLC v2 | aidlc-workflows commit 47b4edcf(2026-05-29) |
| モデル | Claude Opus 4.8 / Claude Sonnet 4.6 |
| 検証日 | 2026-05-31 |
参考リンク










