diff --git a/builtins/en/facets/instructions/implement-terraform.md b/builtins/en/facets/instructions/implement-terraform.md new file mode 100644 index 0000000..1cfa77c --- /dev/null +++ b/builtins/en/facets/instructions/implement-terraform.md @@ -0,0 +1,54 @@ +Implement Terraform code according to the plan. +Refer only to files within the Report Directory shown in the Piece Context. Do not search or reference other report directories. + +**Important**: After implementation, run the following validations in order: +1. `terraform fmt -check` — fix formatting violations with `terraform fmt` if any +2. `terraform validate` — check for syntax and type errors +3. `terraform plan` — verify changes (no unintended modifications) + +**Constraints:** +- Never execute `terraform apply` +- Never write secrets (passwords, tokens) in code +- Do not remove existing `lifecycle { prevent_destroy = true }` without approval +- All new variables must have `type` and `description` + +**Scope output contract (create at the start of implementation):** +```markdown +# Change Scope Declaration + +## Task +{One-line task summary} + +## Planned changes +| Type | File | +|------|------| +| Create | `modules/example/main.tf` | +| Modify | `environments/sandbox/main.tf` | + +## Estimated size +Small / Medium / Large + +## Impact area +- {Affected modules or resources} +``` + +**Decisions output contract (at implementation completion, only if decisions were made):** +```markdown +# Decision Log + +## 1. {Decision} +- **Context**: {Why the decision was needed} +- **Options considered**: {List of options} +- **Rationale**: {Reason for the choice} +- **Cost impact**: {If applicable} +``` + +**Required output (include headings)** +## Work results +- {Summary of actions taken} +## Changes made +- {Summary of changes} +## Validation results +- {terraform fmt -check result} +- {terraform validate result} +- {terraform plan summary (resources to add/change/destroy)} diff --git a/builtins/en/facets/instructions/review-terraform.md b/builtins/en/facets/instructions/review-terraform.md new file mode 100644 index 0000000..c2c7840 --- /dev/null +++ b/builtins/en/facets/instructions/review-terraform.md @@ -0,0 +1,25 @@ +Focus on reviewing **Terraform convention compliance**. +Do not review AI-specific issues (already covered by the ai_review movement). + +**Review criteria:** +- Variable declaration compliance (type, description, sensitive) +- Resource naming consistency (name_prefix pattern) +- File organization compliance (one file per concern) +- Security configurations (IMDSv2, encryption, access control, IAM least privilege) +- Tag management (default_tags, no duplication) +- Lifecycle rule appropriateness +- Cost trade-off documentation +- Unused variables / outputs / data sources + +**Previous finding tracking (required):** +- First, extract open findings from "Previous Response" +- Assign `finding_id` to each finding and classify current status as `new / persists / resolved` +- If status is `persists`, provide concrete unresolved evidence (file/line) + +## Judgment Procedure + +1. First, extract previous open findings and preliminarily classify as `new / persists / resolved` +2. Review the change diff and detect issues based on Terraform convention criteria + - Cross-check changes against REJECT criteria tables defined in knowledge +3. For each detected issue, classify as blocking/non-blocking based on Policy's scope determination table and judgment rules +4. If there is even one blocking issue (`new` or `persists`), judge as REJECT diff --git a/builtins/en/facets/knowledge/terraform-aws.md b/builtins/en/facets/knowledge/terraform-aws.md new file mode 100644 index 0000000..c8795d8 --- /dev/null +++ b/builtins/en/facets/knowledge/terraform-aws.md @@ -0,0 +1,241 @@ +# Terraform AWS Knowledge + +## Module Design + +Split modules by domain (network, database, application layer). Do not create generic utility modules. + +| Criteria | Judgment | +|----------|----------| +| Domain-based module splitting | OK | +| Generic "utils" module | REJECT | +| Unrelated resources mixed in one module | REJECT | +| Implicit inter-module dependencies | REJECT (connect explicitly via outputs→inputs) | + +### Inter-Module Dependencies + +Pass dependencies explicitly via outputs→inputs. Avoid implicit references (using `data` sources to look up other module resources). + +```hcl +# OK - Explicit dependency +module "database" { + source = "../../modules/database" + vpc_id = module.network.vpc_id + subnet_ids = module.network.private_subnet_ids +} + +# NG - Implicit dependency +module "database" { + source = "../../modules/database" + # vpc_id not passed; module uses data "aws_vpc" internally +} +``` + +### Identification Variable Passthrough + +Pass identification variables (environment, service name) explicitly from root to child modules. Do not rely on globals or hardcoding. + +```hcl +# OK - Explicit passthrough +module "database" { + environment = var.environment + service = var.service + application_name = var.application_name +} +``` + +## Resource Naming Convention + +Compute `name_prefix` in `locals` and apply consistently to all resources. Append resource-specific suffixes. + +| Criteria | Judgment | +|----------|----------| +| Unified naming with `name_prefix` pattern | OK | +| Inconsistent naming across resources | REJECT | +| Name exceeds AWS character limits | REJECT | +| Tag names not in PascalCase | Warning | + +```hcl +# OK - Unified with name_prefix +locals { + name_prefix = "${var.environment}-${var.service}-${var.application_name}" +} + +resource "aws_ecs_cluster" "main" { + name = "${local.name_prefix}-cluster" +} + +# NG - Inconsistent naming +resource "aws_ecs_cluster" "main" { + name = "${var.environment}-app-cluster" +} +``` + +### Character Limit Handling + +AWS services have name character limits. Use shortened forms when approaching limits. + +| Service | Limit | Example | +|---------|-------|---------| +| Target Group | 32 chars | `${var.environment}-${var.service}-backend-tg` | +| Lambda Function | 64 chars | Full prefix OK | +| S3 Bucket | 63 chars | Full prefix OK | + +## Tagging Strategy + +Use provider `default_tags` for common tags. No duplicate tagging on individual resources. + +| Criteria | Judgment | +|----------|----------| +| Centralized via provider `default_tags` | OK | +| Duplicate tags matching `default_tags` on individual resources | Warning | +| Only `Name` tag added on individual resources | OK | + +```hcl +# OK - Centralized, individual gets Name only +provider "aws" { + default_tags { + tags = { + Environment = var.environment + ManagedBy = "Terraform" + } + } +} + +resource "aws_instance" "main" { + tags = { + Name = "${local.name_prefix}-instance" + } +} + +# NG - Duplicates default_tags +resource "aws_instance" "main" { + tags = { + Environment = var.environment + ManagedBy = "Terraform" + Name = "${local.name_prefix}-instance" + } +} +``` + +## File Organization Patterns + +### Environment Directory Structure + +Separate environments into directories, each with independent state management. + +``` +environments/ +├── production/ +│ ├── terraform.tf # Version constraints +│ ├── providers.tf # Provider config (default_tags) +│ ├── backend.tf # S3 backend +│ ├── variables.tf # Environment variables +│ ├── main.tf # Module invocations +│ └── outputs.tf # Outputs +└── staging/ + └── ... +``` + +### Module File Structure + +| File | Contents | +|------|----------| +| `main.tf` | `locals` and `data` sources only | +| `variables.tf` | Input variable definitions only (no resources) | +| `outputs.tf` | Output definitions only (no resources) | +| `{resource_type}.tf` | One file per resource category | +| `templates/` | user_data scripts and other templates | + +## Security Best Practices + +### EC2 Instance Security + +| Setting | Recommended | Reason | +|---------|-------------|--------| +| `http_tokens` | `"required"` | Enforce IMDSv2 (SSRF prevention) | +| `http_put_response_hop_limit` | `1` | Prevent container escapes | +| `root_block_device.encrypted` | `true` | Data-at-rest encryption | + +### S3 Bucket Security + +Block all public access with all four settings. Use OAC (Origin Access Control) for CloudFront distributions. + +```hcl +# OK - Complete block +resource "aws_s3_bucket_public_access_block" "this" { + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} +``` + +### IAM Design + +| Pattern | Recommendation | +|---------|---------------| +| Per-service role separation | Separate execution role (for ECS Agent) and task role (for app) | +| CI/CD authentication | OIDC federation (avoid long-lived credentials) | +| Policy scope | Specify resource ARNs explicitly (avoid `"*"`) | + +### Secret Management + +| Method | Recommendation | +|--------|---------------| +| SSM Parameter Store (SecureString) | Recommended | +| Secrets Manager | Recommended (when rotation needed) | +| Direct in `.tfvars` | Conditional OK (gitignore required) | +| Hardcoded in `.tf` files | REJECT | + +Set SSM Parameter initial values to placeholders and use `lifecycle { ignore_changes = [value] }` to manage outside Terraform. + +## Cost Optimization Patterns + +Document trade-offs with inline comments for cost-impacting choices. + +| Choice | Cost Effect | Trade-off | +|--------|------------|-----------| +| NAT Instance vs NAT Gateway | Instance ~$3-4/mo vs Gateway ~$32/mo | Lower availability and throughput | +| Public subnet placement | No VPC Endpoints needed | Weaker network isolation | +| EC2 + EBS vs RDS | EC2 ~$15-20/mo vs RDS ~$50+/mo | Higher operational burden | + +```hcl +# OK - Trade-off documented +# Using t3.nano instead of NAT Gateway (~$3-4/mo vs ~$32/mo) +# Trade-off: single-AZ availability, throughput limits +resource "aws_instance" "nat" { + instance_type = "t3.nano" +} +``` + +## Lifecycle Rule Usage + +| Rule | Purpose | Target | +|------|---------|--------| +| `prevent_destroy` | Prevent accidental deletion | Databases, EBS volumes | +| `ignore_changes` | Allow external changes | `desired_count` (Auto Scaling), SSM `value` | +| `create_before_destroy` | Prevent downtime | Load balancers, security groups | + +```hcl +# OK - Prevent accidental database deletion +resource "aws_instance" "database" { + lifecycle { + prevent_destroy = true + } +} + +# OK - Let Auto Scaling manage desired_count +resource "aws_ecs_service" "main" { + lifecycle { + ignore_changes = [desired_count] + } +} +``` + +## Version Management + +| Setting | Recommendation | +|---------|---------------| +| `required_version` | `">= 1.5.0"` or higher (`default_tags` support) | +| Provider version | Pin minor version with `~>` (e.g., `~> 5.80`) | +| State locking | `use_lockfile = true` required | diff --git a/builtins/en/facets/output-contracts/terraform-review.md b/builtins/en/facets/output-contracts/terraform-review.md new file mode 100644 index 0000000..cc73d19 --- /dev/null +++ b/builtins/en/facets/output-contracts/terraform-review.md @@ -0,0 +1,42 @@ +```markdown +# Terraform Convention Review + +## Result: APPROVE / REJECT + +## Summary +{1-2 sentences summarizing the result} + +## Reviewed Aspects +- [x] Variable declarations (type, description, sensitive) +- [x] Resource naming (name_prefix pattern) +- [x] File organization (one file per concern) +- [x] Security configurations +- [x] Tag management +- [x] Lifecycle rules +- [x] Cost trade-off documentation + +## New Findings (new) +| # | finding_id | Scope | Location | Issue | Fix Suggestion | +|---|------------|-------|----------|-------|---------------| +| 1 | TF-NEW-file-L42 | In scope | `modules/example/main.tf:42` | Issue description | How to fix | + +Scope: "In scope" (fixable now) / "Out of scope" (existing issue, non-blocking) + +## Persisting Findings (persists) +| # | finding_id | Previous Evidence | Current Evidence | Issue | Fix Suggestion | +|---|------------|-------------------|------------------|-------|---------------| +| 1 | TF-PERSIST-file-L77 | `file.tf:77` | `file.tf:77` | Unresolved | Apply existing fix plan | + +## Resolved +| finding_id | Resolution Evidence | +|------------|-------------------| +| TF-RESOLVED-file-L10 | `file.tf:10` meets conventions | + +## REJECT Criteria +- REJECT only if 1+ `new` or `persists` findings exist +- Findings without `finding_id` are invalid +``` + +**Cognitive load reduction rules:** +- APPROVE → Summary only (5 lines or less) +- REJECT → Only relevant findings in table (30 lines or less) diff --git a/builtins/en/facets/personas/terraform-coder.md b/builtins/en/facets/personas/terraform-coder.md new file mode 100644 index 0000000..ab3487c --- /dev/null +++ b/builtins/en/facets/personas/terraform-coder.md @@ -0,0 +1,30 @@ +# Terraform Coder + +You are a Terraform/AWS infrastructure implementation specialist. You write safe, maintainable infrastructure code following IaC principles. + +## Role Boundaries + +**Do:** +- Create and modify Terraform code (.tf files) +- Design modules and define variables +- Implement security configurations (IAM, security groups, encryption) +- Make cost optimization decisions and document trade-offs + +**Don't:** +- Implement application code (implementation agent's responsibility) +- Make final infrastructure design decisions (planning/design agent's responsibility) +- Apply changes to production (`terraform apply` is never executed) + +## Behavioral Principles + +- Safety over speed. Infrastructure misconfigurations have greater impact than application bugs +- Don't guess configurations; verify with official documentation +- Never write secrets (passwords, tokens) in code +- Document trade-offs with inline comments for cost-impacting choices +- Security is strict by default. Only relax explicitly with justification + +**Be aware of AI's bad habits:** +- Writing nonexistent resource attributes or provider arguments → Prohibited (verify with official docs) +- Casually opening security groups to `0.0.0.0/0` → Prohibited +- Writing unused variables or outputs "just in case" → Prohibited +- Adding `depends_on` where implicit dependencies suffice → Prohibited diff --git a/builtins/en/facets/personas/terraform-reviewer.md b/builtins/en/facets/personas/terraform-reviewer.md new file mode 100644 index 0000000..742526e --- /dev/null +++ b/builtins/en/facets/personas/terraform-reviewer.md @@ -0,0 +1,25 @@ +# Terraform Reviewer + +You are an IaC (Infrastructure as Code) convention specialist reviewer. You verify that Terraform code complies with project conventions and security standards. + +## Role Boundaries + +**Do:** +- Verify Terraform convention compliance (naming, file organization, variable declarations) +- Validate security configurations (IAM least privilege, encryption, access control) +- Detect cost impacts and verify trade-off documentation +- Validate `lifecycle` rule appropriateness + +**Don't:** +- Write code yourself (only provide findings and fix suggestions) +- Review AI-specific issues (separate review agent's responsibility) +- Review application code (design review agent's responsibility) +- Execute `terraform plan` (validation agent's responsibility) + +## Behavioral Principles + +- No compromises on security issues. Missing encryption or public access exposure is an immediate REJECT +- Enforce naming consistency. Even one off-convention name gets flagged +- Flag cost-impacting choices that lack trade-off documentation +- No "conditional approvals". If there are issues, reject +- Never miss unused variables/outputs/data sources diff --git a/builtins/en/facets/policies/terraform.md b/builtins/en/facets/policies/terraform.md new file mode 100644 index 0000000..1a00ca0 --- /dev/null +++ b/builtins/en/facets/policies/terraform.md @@ -0,0 +1,88 @@ +# Terraform Policy + +Prioritize safety and maintainability. Write infrastructure code following consistent conventions. + +## Principles + +| Principle | Criteria | +|-----------|----------| +| Security by Default | Security is strict by default. Relaxation requires explicit justification | +| Fail Fast | No defaults for required values. Missing values must error immediately | +| Naming Consistency | Unified resource naming via `name_prefix` pattern | +| Least Privilege | IAM scoped to minimum necessary actions and resources | +| Cost Awareness | Document trade-offs with inline comments | +| DRY | Compute common values in `locals`. Eliminate duplication | +| One File One Concern | Split files by resource category | + +## Variable Declarations + +| Criteria | Judgment | +|----------|----------| +| Missing `type` | REJECT | +| Missing `description` | REJECT | +| Sensitive value without `sensitive = true` | REJECT | +| Default on environment-dependent value | REJECT | +| Default on constant value (port numbers, etc.) | OK | + +```hcl +# REJECT - no type/description +variable "region" {} + +# REJECT - sensitive value without sensitive flag +variable "db_password" { + type = string +} + +# OK - constant value with default +variable "container_port" { + type = number + description = "Container port for the application" + default = 8080 +} +``` + +## Security + +| Criteria | Judgment | +|----------|----------| +| EC2 without IMDSv2 (`http_tokens != "required"`) | REJECT | +| Unencrypted EBS/RDS | REJECT | +| S3 without public access block | REJECT | +| Security group with unnecessary `0.0.0.0/0` | REJECT | +| IAM policy with `*` resource (no valid reason) | REJECT | +| Direct SSH access (when SSM is viable) | REJECT | +| Hardcoded secrets | REJECT | +| Missing `lifecycle { prevent_destroy = true }` on critical data | Warning | + +## Naming Convention + +| Criteria | Judgment | +|----------|----------| +| `name_prefix` pattern not used | REJECT | +| Resource name missing environment identifier | REJECT | +| Tag names not in PascalCase | Warning | +| Name exceeds AWS character limits | REJECT | + +## File Organization + +| Criteria | Judgment | +|----------|----------| +| Resource definitions mixed in `main.tf` | REJECT | +| Resources defined in `variables.tf` | REJECT | +| Multiple resource categories in one file | Warning | +| Unused variable / output / data source | REJECT | + +## Tag Management + +| Criteria | Judgment | +|----------|----------| +| Provider `default_tags` not configured | REJECT | +| Tags duplicated between `default_tags` and individual resources | Warning | +| Missing `ManagedBy = "Terraform"` tag | Warning | + +## Cost Management + +| Criteria | Judgment | +|----------|----------| +| Cost-impacting choice without documentation | Warning | +| High-cost resource without alternative consideration | Warning | diff --git a/builtins/en/piece-categories.yaml b/builtins/en/piece-categories.yaml index 549d5a0..d2fb133 100644 --- a/builtins/en/piece-categories.yaml +++ b/builtins/en/piece-categories.yaml @@ -31,6 +31,9 @@ piece_categories: - expert-mini - expert-cqrs - expert-cqrs-mini + 🏗️ Infrastructure: + pieces: + - terraform 🛠️ Refactoring: pieces: - structural-reform diff --git a/builtins/en/pieces/terraform.yaml b/builtins/en/pieces/terraform.yaml new file mode 100644 index 0000000..c47977a --- /dev/null +++ b/builtins/en/pieces/terraform.yaml @@ -0,0 +1,296 @@ +name: terraform +description: Terraform IaC development piece (plan → implement → parallel review → supervisor validation → fix → complete) +piece_config: + provider_options: + codex: + network_access: true + opencode: + network_access: true +max_movements: 15 +initial_movement: plan +movements: + - name: plan + edit: false + persona: planner + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + rules: + - condition: Requirements are clear and implementable + next: implement + - condition: User is asking a question (not an implementation task) + next: COMPLETE + - condition: Requirements are unclear or insufficient + next: ABORT + instruction: plan + output_contracts: + report: + - name: plan.md + format: plan + - name: implement + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + quality_gates: + - terraform fmt -check passes without errors + - terraform validate succeeds + - terraform plan is executable (no errors) + instruction: implement-terraform + rules: + - condition: Implementation is complete + next: reviewers + - condition: Cannot proceed with implementation + next: ABORT + - condition: User input needed for confirmation + next: implement + requires_user_input: true + interactive_only: true + output_contracts: + report: + - name: coder-scope.md + format: coder-scope + - name: coder-decisions.md + format: coder-decisions + - name: reviewers + parallel: + - name: tf_review + edit: false + persona: terraform-reviewer + policy: + - review + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + instruction: review-terraform + rules: + - condition: Complies with Terraform conventions + - condition: Convention violations found + output_contracts: + report: + - name: terraform-review.md + format: terraform-review + - name: ai_review + edit: false + persona: ai-antipattern-reviewer + policy: + - review + - ai-antipattern + allowed_tools: + - Read + - Glob + - Grep + - WebSearch + - WebFetch + instruction: review-ai + rules: + - condition: No AI-specific issues + - condition: AI-specific issues found + output_contracts: + report: + - name: ai-review.md + format: ai-review + rules: + - condition: all("Complies with Terraform conventions", "No AI-specific issues") + next: supervise + - condition: any("Convention violations found", "AI-specific issues found") + next: supervise + - name: supervise + edit: false + persona: supervisor + policy: review + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + instruction: supervise + rules: + - condition: All reviewers approved and task requirements met + next: COMPLETE + - condition: Only AI-specific issues need fixing + next: ai_fix + - condition: Only convention violations or requirements unmet + next: supervise_fix + - condition: Multiple types of issues found + next: fix_both + - condition: Irreconcilable requirement conflict, user decision needed + next: ABORT + output_contracts: + report: + - name: supervisor-validation.md + format: supervisor-validation + - name: summary.md + format: summary + use_judge: false + - name: fix_both + parallel: + - name: ai_fix_parallel + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + rules: + - condition: AI issue fix complete + - condition: No fix needed (target file/spec verified) + - condition: Cannot determine, insufficient info + instruction: ai-fix + - name: supervise_fix_parallel + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + rules: + - condition: Supervisor's findings have been fixed + - condition: Cannot proceed with fix + instruction: fix-supervisor + rules: + - condition: all("AI issue fix complete", "Supervisor's findings have been fixed") + next: reviewers + - condition: any("No fix needed (target file/spec verified)", "Cannot determine, insufficient info", "Cannot proceed with fix") + next: implement + - name: ai_fix + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + pass_previous_response: false + rules: + - condition: AI issue fix complete + next: reviewers + - condition: No fix needed (target file/spec verified) + next: implement + - condition: Cannot determine, insufficient info + next: implement + instruction: ai-fix + - name: supervise_fix + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + pass_previous_response: false + rules: + - condition: Supervisor's findings have been fixed + next: reviewers + - condition: Cannot proceed with fix + next: implement + instruction: fix-supervisor +loop_monitors: + - cycle: [fix_both, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + The review → fix cycle has repeated {cycle_count} times. + Check the review report history in the Report Directory and assess convergence. + + **Signs of unproductive cycling:** + - Same finding_id oscillating between resolved → new + - New issues keep arising as side effects of previous fixes + - Reviewer findings conflict with task requirements and cannot be reconciled + rules: + - condition: Healthy (new issues trending down) + next: fix_both + - condition: Unproductive (oscillation or requirement conflict) + next: ABORT + - cycle: [ai_fix, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + The AI fix → review cycle has repeated {cycle_count} times. + Check the review report history in the Report Directory and assess convergence. + + **Signs of unproductive cycling:** + - Same finding_id oscillating between resolved → new + - New issues keep arising as side effects of previous fixes + - Reviewer findings conflict with task requirements and cannot be reconciled + rules: + - condition: Healthy (new issues trending down) + next: ai_fix + - condition: Unproductive (oscillation or requirement conflict) + next: ABORT + - cycle: [supervise_fix, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + The supervisor fix → review cycle has repeated {cycle_count} times. + Check the review report history in the Report Directory and assess convergence. + + **Signs of unproductive cycling:** + - Same finding_id oscillating between resolved → new + - New issues keep arising as side effects of previous fixes + - Reviewer findings conflict with task requirements and cannot be reconciled + rules: + - condition: Healthy (new issues trending down) + next: supervise_fix + - condition: Unproductive (oscillation or requirement conflict) + next: ABORT diff --git a/builtins/ja/facets/instructions/implement-terraform.md b/builtins/ja/facets/instructions/implement-terraform.md new file mode 100644 index 0000000..56077a9 --- /dev/null +++ b/builtins/ja/facets/instructions/implement-terraform.md @@ -0,0 +1,54 @@ +計画に従って Terraform コードを実装してください。 +Piece Contextに示されたReport Directory内のファイルのみ参照してください。他のレポートディレクトリは検索/参照しないでください。 + +**重要**: 実装完了後、以下の検証を順番に実行してください。 +1. `terraform fmt -check` — フォーマット違反があれば `terraform fmt` で修正 +2. `terraform validate` — 構文・型エラーの確認 +3. `terraform plan` — 変更内容の確認(意図しない変更がないこと) + +**注意事項:** +- `terraform apply` は絶対に実行しない +- 機密情報(パスワード、トークン)をコードに書かない +- 既存リソースの `lifecycle { prevent_destroy = true }` を無断で削除しない +- 新しい variable を追加する場合は `type` と `description` を必ず付ける + +**Scope出力契約(実装開始時に作成):** +```markdown +# 変更スコープ宣言 + +## タスク +{タスクの1行要約} + +## 変更予定 +| 種別 | ファイル | +|------|---------| +| 作成 | `modules/example/main.tf` | +| 変更 | `environments/sandbox/main.tf` | + +## 推定規模 +Small / Medium / Large + +## 影響範囲 +- {影響するモジュールやリソース} +``` + +**Decisions出力契約(実装完了時、決定がある場合のみ):** +```markdown +# 決定ログ + +## 1. {決定内容} +- **背景**: {なぜ決定が必要だったか} +- **検討した選択肢**: {選択肢リスト} +- **理由**: {選んだ理由} +- **コスト影響**: {ある場合のみ} +``` + +**必須出力(見出しを含める)** +## 作業結果 +- {実施内容の要約} +## 変更内容 +- {変更内容の要約} +## 検証結果 +- {terraform fmt -check の結果} +- {terraform validate の結果} +- {terraform plan の結果サマリー(追加/変更/削除のリソース数)} diff --git a/builtins/ja/facets/instructions/review-terraform.md b/builtins/ja/facets/instructions/review-terraform.md new file mode 100644 index 0000000..3975fc9 --- /dev/null +++ b/builtins/ja/facets/instructions/review-terraform.md @@ -0,0 +1,25 @@ +**Terraform 規約準拠**のレビューに集中してください。 +AI特有の問題はレビューしないでください(ai_reviewムーブメントで実施済み)。 + +**レビュー観点:** +- 変数宣言の規約準拠(type, description, sensitive) +- リソース命名の一貫性(name_prefix パターン) +- ファイル構成の規約準拠(1ファイル1関心事) +- セキュリティ設定(IMDSv2, 暗号化, アクセス制御, IAM最小権限) +- タグ管理(default_tags, 重複なし) +- lifecycle ルールの妥当性 +- コストトレードオフの文書化 +- 未使用の variable / output / data source + +**前回指摘の追跡(必須):** +- まず「Previous Response」から前回の open findings を抽出する +- 各 finding に `finding_id` を付け、今回の状態を `new / persists / resolved` で判定する +- `persists` と判定する場合は、未解決である根拠(ファイル/行)を必ず示す + +## 判定手順 + +1. まず前回open findingsを抽出し、`new / persists / resolved` を仮判定する +2. 変更差分を確認し、Terraform規約の観点に基づいて問題を検出する + - ナレッジの判定基準テーブル(REJECT条件)と変更内容を照合する +3. 検出した問題ごとに、Policyのスコープ判定表と判定ルールに基づいてブロッキング/非ブロッキングを分類する +4. ブロッキング問題(`new` または `persists`)が1件でもあればREJECTと判定する diff --git a/builtins/ja/facets/knowledge/terraform-aws.md b/builtins/ja/facets/knowledge/terraform-aws.md new file mode 100644 index 0000000..8897c0e --- /dev/null +++ b/builtins/ja/facets/knowledge/terraform-aws.md @@ -0,0 +1,241 @@ +# Terraform AWS 知識 + +## モジュール設計 + +モジュールはドメイン(ネットワーク、データベース、アプリケーション層)単位で分割する。汎用ユーティリティモジュールは作らない。 + +| 基準 | 判定 | +|------|------| +| ドメイン単位のモジュール分割 | OK | +| 汎用 "utils" モジュール | REJECT | +| 1モジュールに無関係なリソースが混在 | REJECT | +| モジュール間の暗黙的依存 | REJECT(出力→入力で明示的に接続) | + +### モジュール間の依存 + +モジュール間の依存は出力→入力で明示的に渡す。暗黙的な参照(`data` ソースで他モジュールのリソースを引く)は避ける。 + +```hcl +# OK - 明示的な依存 +module "database" { + source = "../../modules/database" + vpc_id = module.network.vpc_id + subnet_ids = module.network.private_subnet_ids +} + +# NG - 暗黙的な依存 +module "database" { + source = "../../modules/database" + # vpc_id を渡さず、module 内で data "aws_vpc" で引いている +} +``` + +### 識別変数のパススルー + +環境名・サービス名などの識別変数は、ルートモジュールから子モジュールへ明示的に渡す。グローバル変数やハードコードに頼らない。 + +```hcl +# OK - 明示的なパススルー +module "database" { + environment = var.environment + service = var.service + application_name = var.application_name +} +``` + +## リソース命名規約 + +`locals` で `name_prefix` を計算し、全リソースに一貫して適用する。リソース固有のサフィックスを付加する。 + +| 基準 | 判定 | +|------|------| +| `name_prefix` パターンで統一命名 | OK | +| 各リソースでバラバラに命名 | REJECT | +| AWS 文字数制限を超える名前 | REJECT | +| タグ名が PascalCase でない | 警告 | + +```hcl +# OK - name_prefix で統一 +locals { + name_prefix = "${var.environment}-${var.service}-${var.application_name}" +} + +resource "aws_ecs_cluster" "main" { + name = "${local.name_prefix}-cluster" +} + +# NG - 各リソースでバラバラに命名 +resource "aws_ecs_cluster" "main" { + name = "${var.environment}-app-cluster" +} +``` + +### 文字数制限への対応 + +AWS サービスには名前の文字数制限がある。制限に近い場合は短縮形を使う。 + +| サービス | 制限 | 例 | +|---------|------|-----| +| Target Group | 32文字 | `${var.environment}-${var.service}-backend-tg` | +| Lambda 関数 | 64文字 | フルプレフィックス可 | +| S3 バケット | 63文字 | フルプレフィックス可 | + +## タグ戦略 + +provider の `default_tags` で共通タグを一括設定する。個別リソースでの重複タグ付けは不要。 + +| 基準 | 判定 | +|------|------| +| provider `default_tags` で一括設定 | OK | +| 個別リソースで `default_tags` と同じタグを重複設定 | 警告 | +| 個別リソースで `Name` タグのみ追加 | OK | + +```hcl +# OK - provider で一括、個別は Name のみ +provider "aws" { + default_tags { + tags = { + Environment = var.environment + ManagedBy = "Terraform" + } + } +} + +resource "aws_instance" "main" { + tags = { + Name = "${local.name_prefix}-instance" + } +} + +# NG - default_tags と重複 +resource "aws_instance" "main" { + tags = { + Environment = var.environment + ManagedBy = "Terraform" + Name = "${local.name_prefix}-instance" + } +} +``` + +## ファイル構成パターン + +### 環境ディレクトリ構造 + +環境ごとにディレクトリを分離し、各環境が独立した状態管理を持つ。 + +``` +environments/ +├── production/ +│ ├── terraform.tf # バージョン制約 +│ ├── providers.tf # プロバイダ設定(default_tags) +│ ├── backend.tf # S3 バックエンド +│ ├── variables.tf # 環境変数 +│ ├── main.tf # モジュール呼び出し +│ └── outputs.tf # 出力 +└── staging/ + └── ... +``` + +### モジュール内ファイル構成 + +| ファイル | 内容 | +|---------|------| +| `main.tf` | `locals`、`data` ソースのみ | +| `variables.tf` | 入力変数定義のみ(リソースなし) | +| `outputs.tf` | 出力定義のみ(リソースなし) | +| `{resource_type}.tf` | リソースカテゴリごとに1ファイル | +| `templates/` | user_data スクリプト等のテンプレート | + +## セキュリティベストプラクティス + +### EC2 インスタンスセキュリティ + +| 設定 | 推奨値 | 理由 | +|------|--------|------| +| `http_tokens` | `"required"` | IMDSv2 強制(SSRF 防止) | +| `http_put_response_hop_limit` | `1` | コンテナエスケープ防止 | +| `root_block_device.encrypted` | `true` | 保存データ暗号化 | + +### S3 バケットセキュリティ + +パブリックアクセスは4項目すべてブロックする。CloudFront 経由の場合は OAC(Origin Access Control)を使用する。 + +```hcl +# OK - 完全ブロック +resource "aws_s3_bucket_public_access_block" "this" { + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} +``` + +### IAM 設計 + +| パターン | 推奨 | +|---------|------| +| 用途別ロール分離 | 実行ロール(ECS Agent 用)とタスクロール(アプリ用)を分ける | +| CI/CD 認証 | OIDC フェデレーション(長期認証情報を使わない) | +| ポリシースコープ | リソース ARN を明示的に指定(`"*"` を避ける) | + +### 機密情報管理 + +| 方法 | 推奨度 | +|------|--------| +| SSM Parameter Store(SecureString) | 推奨 | +| Secrets Manager | 推奨(ローテーション必要時) | +| `.tfvars` に直接記載 | 条件付きOK(gitignore 必須) | +| `.tf` ファイルにハードコード | REJECT | + +SSM Parameter の初期値はプレースホルダーにし、`lifecycle { ignore_changes = [value] }` で Terraform 管理外にする。 + +## コスト最適化パターン + +コスト影響のある選択にはインラインコメントでトレードオフを文書化する。 + +| 選択 | コスト効果 | トレードオフ | +|------|-----------|------------| +| NAT Instance vs NAT Gateway | NAT Instance は月額 ~$3-4 vs Gateway ~$32 | 可用性・スループットが劣る | +| パブリックサブネット配置 | VPC Endpoint 不要 | ネットワーク分離が弱まる | +| EC2 + EBS vs RDS | EC2 は月額 ~$15-20 vs RDS ~$50+ | 運用負荷が増える | + +```hcl +# OK - トレードオフを文書化 +# NAT Gateway の代わりに t3.nano を使用(約 $3-4/月 vs $32/月) +# トレードオフ: 可用性は単一AZ、スループット上限あり +resource "aws_instance" "nat" { + instance_type = "t3.nano" +} +``` + +## Lifecycle ルールの使い分け + +| ルール | 用途 | 適用対象 | +|--------|------|---------| +| `prevent_destroy` | 誤削除防止 | データベース、EBS ボリューム | +| `ignore_changes` | 外部変更を許容 | `desired_count`(Auto Scaling)、SSM の `value` | +| `create_before_destroy` | ダウンタイム防止 | ロードバランサー、セキュリティグループ | + +```hcl +# OK - データベースの誤削除防止 +resource "aws_instance" "database" { + lifecycle { + prevent_destroy = true + } +} + +# OK - Auto Scaling の desired_count を Terraform 管理外にする +resource "aws_ecs_service" "main" { + lifecycle { + ignore_changes = [desired_count] + } +} +``` + +## バージョン管理 + +| 設定 | 推奨 | +|------|------| +| `required_version` | `">= 1.5.0"` 以上(`default_tags` サポート) | +| プロバイダバージョン | `~>` でマイナーバージョン固定(例: `~> 5.80`) | +| 状態ロック | `use_lockfile = true` 必須 | diff --git a/builtins/ja/facets/output-contracts/terraform-review.md b/builtins/ja/facets/output-contracts/terraform-review.md new file mode 100644 index 0000000..5977b2e --- /dev/null +++ b/builtins/ja/facets/output-contracts/terraform-review.md @@ -0,0 +1,42 @@ +```markdown +# Terraform 規約レビュー + +## 結果: APPROVE / REJECT + +## サマリー +{1-2文で結果を要約} + +## 確認した観点 +- [x] 変数宣言(type, description, sensitive) +- [x] リソース命名(name_prefix パターン) +- [x] ファイル構成(1ファイル1関心事) +- [x] セキュリティ設定 +- [x] タグ管理 +- [x] lifecycle ルール +- [x] コストトレードオフ文書化 + +## 今回の指摘(new) +| # | finding_id | スコープ | 場所 | 問題 | 修正案 | +|---|------------|---------|------|------|--------| +| 1 | TF-NEW-file-L42 | スコープ内 | `modules/example/main.tf:42` | 問題の説明 | 修正方法 | + +スコープ: 「スコープ内」(今回修正可能)/ 「スコープ外」(既存問題・非ブロッキング) + +## 継続指摘(persists) +| # | finding_id | 前回根拠 | 今回根拠 | 問題 | 修正案 | +|---|------------|----------|----------|------|--------| +| 1 | TF-PERSIST-file-L77 | `file.tf:77` | `file.tf:77` | 未解消 | 既存修正方針を適用 | + +## 解消済み(resolved) +| finding_id | 解消根拠 | +|------------|----------| +| TF-RESOLVED-file-L10 | `file.tf:10` は規約を満たす | + +## REJECT判定条件 +- `new` または `persists` が1件以上ある場合のみ REJECT 可 +- `finding_id` なしの指摘は無効 +``` + +**認知負荷軽減ルール:** +- APPROVE → サマリーのみ(5行以内) +- REJECT → 該当指摘のみ表で記載(30行以内) diff --git a/builtins/ja/facets/personas/terraform-coder.md b/builtins/ja/facets/personas/terraform-coder.md new file mode 100644 index 0000000..52e0955 --- /dev/null +++ b/builtins/ja/facets/personas/terraform-coder.md @@ -0,0 +1,30 @@ +# Terraform Coder + +あなたはTerraform/AWS インフラストラクチャの実装専門家です。IaCの原則に従い、安全で保守性の高いインフラコードを書きます。 + +## 役割の境界 + +**やること:** +- Terraform コード(.tf ファイル)の作成・修正 +- モジュール設計と変数定義 +- セキュリティ設定の実装(IAM、セキュリティグループ、暗号化) +- コスト最適化の判断と文書化 + +**やらないこと:** +- アプリケーションコードの実装(実装担当の責務) +- インフラ設計の最終決定(設計担当の責務) +- 本番環境への直接適用(`terraform apply` は実行しない) + +## 行動姿勢 + +- 速さより安全性。インフラの誤設定はアプリケーションバグより影響が大きい +- 推測で設定せず、公式ドキュメントで確認する +- 機密情報(パスワード、トークン)は絶対にコードに書かない +- コスト影響のある選択にはコメントでトレードオフを文書化する +- セキュリティはデフォルトで厳格に。緩和が必要な場合のみ明示的に開放する + +**AI の悪い癖を自覚する:** +- 存在しないリソース属性やプロバイダ引数を書く → 禁止(公式ドキュメントで確認) +- セキュリティグループで `0.0.0.0/0` を安易に開放する → 禁止 +- 未使用の variable や output を「念のため」書く → 禁止 +- `depends_on` を暗黙的依存で十分な箇所に追加する → 禁止 diff --git a/builtins/ja/facets/personas/terraform-reviewer.md b/builtins/ja/facets/personas/terraform-reviewer.md new file mode 100644 index 0000000..8b27ba1 --- /dev/null +++ b/builtins/ja/facets/personas/terraform-reviewer.md @@ -0,0 +1,25 @@ +# Terraform Reviewer + +あなたはIaC(Infrastructure as Code)規約の専門レビュアーです。Terraformコードがプロジェクトの規約とセキュリティ基準に準拠しているかを検証します。 + +## 役割の境界 + +**やること:** +- Terraform 規約準拠の検証(命名、ファイル構成、変数宣言) +- セキュリティ設定の検証(IAM最小権限、暗号化、アクセス制御) +- コスト影響の検出とトレードオフ文書化の確認 +- `lifecycle` ルールの妥当性検証 + +**やらないこと:** +- 自分でコードを書く(指摘と修正案の提示のみ) +- AI特有の問題のレビュー(別のレビュー担当の責務) +- アプリケーションコードのレビュー(設計レビュー担当の責務) +- `terraform plan` の実行(検証担当の責務) + +## 行動姿勢 + +- セキュリティ問題は妥協しない。暗号化なし、パブリックアクセス開放は即 REJECT +- 命名の一貫性を重視する。1箇所でも規約外の命名があれば指摘する +- コスト影響のある選択にトレードオフのコメントがなければ指摘する +- 「条件付き承認」はしない。問題があれば差し戻す +- 未使用の variable/output/data source は見逃さない diff --git a/builtins/ja/facets/policies/terraform.md b/builtins/ja/facets/policies/terraform.md new file mode 100644 index 0000000..d8b9b10 --- /dev/null +++ b/builtins/ja/facets/policies/terraform.md @@ -0,0 +1,88 @@ +# Terraform ポリシー + +安全性と保守性を最優先し、一貫した規約に従うインフラコードを書く。 + +## 原則 + +| 原則 | 基準 | +|------|------| +| Security by Default | セキュリティはデフォルトで厳格。緩和は明示的かつ理由付き | +| Fail Fast | 必須値にデフォルトを入れない。不足は即エラー | +| 命名一貫性 | `name_prefix` パターンで全リソースを統一命名 | +| 最小権限 | IAM は必要最小限のアクション・リソースに絞る | +| コスト意識 | トレードオフはコメントで文書化 | +| DRY | `locals` で共通値を計算。重複排除 | +| 1ファイル1関心事 | リソースカテゴリごとにファイル分割 | + +## 変数宣言 + +| 基準 | 判定 | +|------|------| +| `type` なし | REJECT | +| `description` なし | REJECT | +| 機密値に `sensitive = true` なし | REJECT | +| 環境依存値にデフォルト設定 | REJECT | +| 定数的な値(ポート番号等)にデフォルト設定 | OK | + +```hcl +# REJECT - type/description なし +variable "region" {} + +# REJECT - 機密値に sensitive なし +variable "db_password" { + type = string +} + +# OK - 定数的な値にデフォルト +variable "container_port" { + type = number + description = "Container port for the application" + default = 8080 +} +``` + +## セキュリティ + +| 基準 | 判定 | +|------|------| +| EC2 で IMDSv2 未強制(`http_tokens != "required"`) | REJECT | +| EBS/RDS 暗号化なし | REJECT | +| S3 パブリックアクセスブロックなし | REJECT | +| セキュリティグループで `0.0.0.0/0` への不要な開放 | REJECT | +| IAM ポリシーに `*` リソース(正当な理由なし) | REJECT | +| SSH 直接アクセス(SSM 代替可能な場合) | REJECT | +| 機密情報のハードコーディング | REJECT | +| `lifecycle { prevent_destroy = true }` が重要データに未設定 | 警告 | + +## 命名規約 + +| 基準 | 判定 | +|------|------| +| `name_prefix` パターン未使用 | REJECT | +| リソース名に環境名が含まれない | REJECT | +| タグ名が PascalCase でない | 警告 | +| AWS 文字数制限を超える名前 | REJECT | + +## ファイル構成 + +| 基準 | 判定 | +|------|------| +| `main.tf` にリソース定義が混在 | REJECT | +| `variables.tf` にリソースが定義されている | REJECT | +| 1ファイルに複数カテゴリのリソースが混在 | 警告 | +| 未使用の variable / output / data source | REJECT | + +## タグ管理 + +| 基準 | 判定 | +|------|------| +| provider `default_tags` 未設定 | REJECT | +| `default_tags` と個別リソースでタグが重複 | 警告 | +| `ManagedBy = "Terraform"` タグなし | 警告 | + +## コスト管理 + +| 基準 | 判定 | +|------|------| +| コスト影響のある選択にコメントなし | 警告 | +| 高コストリソース(NAT Gateway 等)に代替案の検討なし | 警告 | diff --git a/builtins/ja/piece-categories.yaml b/builtins/ja/piece-categories.yaml index 20fa107..94264f1 100644 --- a/builtins/ja/piece-categories.yaml +++ b/builtins/ja/piece-categories.yaml @@ -31,6 +31,9 @@ piece_categories: - expert-mini - expert-cqrs - expert-cqrs-mini + 🏗️ インフラストラクチャ: + pieces: + - terraform 🛠️ リファクタリング: pieces: - structural-reform diff --git a/builtins/ja/pieces/terraform.yaml b/builtins/ja/pieces/terraform.yaml new file mode 100644 index 0000000..44d2da4 --- /dev/null +++ b/builtins/ja/pieces/terraform.yaml @@ -0,0 +1,296 @@ +name: terraform +description: Terraform IaC 開発ピース(plan → implement → 並列レビュー → 監督検証 → 修正 → 完了) +piece_config: + provider_options: + codex: + network_access: true + opencode: + network_access: true +max_movements: 15 +initial_movement: plan +movements: + - name: plan + edit: false + persona: planner + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + rules: + - condition: 要件が明確で実装可能 + next: implement + - condition: ユーザーが質問をしている(実装タスクではない) + next: COMPLETE + - condition: 要件が不明確、情報不足 + next: ABORT + instruction: plan + output_contracts: + report: + - name: plan.md + format: plan + - name: implement + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + quality_gates: + - terraform fmt -check がエラーなし + - terraform validate が成功 + - terraform plan が実行可能(エラーなし) + instruction: implement-terraform + rules: + - condition: 実装が完了した + next: reviewers + - condition: 実装を進行できない + next: ABORT + - condition: ユーザーへの確認事項があるためユーザー入力が必要 + next: implement + requires_user_input: true + interactive_only: true + output_contracts: + report: + - name: coder-scope.md + format: coder-scope + - name: coder-decisions.md + format: coder-decisions + - name: reviewers + parallel: + - name: tf_review + edit: false + persona: terraform-reviewer + policy: + - review + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + instruction: review-terraform + rules: + - condition: Terraform規約に準拠 + - condition: 規約違反あり + output_contracts: + report: + - name: terraform-review.md + format: terraform-review + - name: ai_review + edit: false + persona: ai-antipattern-reviewer + policy: + - review + - ai-antipattern + allowed_tools: + - Read + - Glob + - Grep + - WebSearch + - WebFetch + instruction: review-ai + rules: + - condition: AI特有の問題なし + - condition: AI特有の問題あり + output_contracts: + report: + - name: ai-review.md + format: ai-review + rules: + - condition: all("Terraform規約に準拠", "AI特有の問題なし") + next: supervise + - condition: any("規約違反あり", "AI特有の問題あり") + next: supervise + - name: supervise + edit: false + persona: supervisor + policy: review + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Bash + - WebSearch + - WebFetch + instruction: supervise + rules: + - condition: レビュアー全員承認かつタスク要件充足 + next: COMPLETE + - condition: AI特有の問題のみ要修正 + next: ai_fix + - condition: 規約違反または要件未達のみ要修正 + next: supervise_fix + - condition: 複数種別の問題あり + next: fix_both + - condition: 要件矛盾で収束不能、ユーザー判断が必要 + next: ABORT + output_contracts: + report: + - name: supervisor-validation.md + format: supervisor-validation + - name: summary.md + format: summary + use_judge: false + - name: fix_both + parallel: + - name: ai_fix_parallel + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + rules: + - condition: AI問題の修正完了 + - condition: 修正不要(指摘対象ファイル/仕様の確認済み) + - condition: 判断できない、情報不足 + instruction: ai-fix + - name: supervise_fix_parallel + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + rules: + - condition: 監督者の指摘に対する修正が完了した + - condition: 修正を進行できない + instruction: fix-supervisor + rules: + - condition: all("AI問題の修正完了", "監督者の指摘に対する修正が完了した") + next: reviewers + - condition: any("修正不要(指摘対象ファイル/仕様の確認済み)", "判断できない、情報不足", "修正を進行できない") + next: implement + - name: ai_fix + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + pass_previous_response: false + rules: + - condition: AI問題の修正完了 + next: reviewers + - condition: 修正不要(指摘対象ファイル/仕様の確認済み) + next: implement + - condition: 判断できない、情報不足 + next: implement + instruction: ai-fix + - name: supervise_fix + edit: true + persona: terraform-coder + policy: + - terraform + knowledge: terraform-aws + allowed_tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash + - WebSearch + - WebFetch + required_permission_mode: full + pass_previous_response: false + rules: + - condition: 監督者の指摘に対する修正が完了した + next: reviewers + - condition: 修正を進行できない + next: implement + instruction: fix-supervisor +loop_monitors: + - cycle: [fix_both, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + レビュー → 修正のサイクルが {cycle_count} 回繰り返されました。 + Report Directory 内のレビューレポート履歴を確認し、収束状況を判断してください。 + + **非生産的の兆候:** + - 同じ finding_id が resolved → new を繰り返している + - 前の修正の副作用で新しい issue が生まれ続けている + - レビュアーの指摘とタスク要件が矛盾しており解消不能 + rules: + - condition: 健全(新しい問題が減少傾向) + next: fix_both + - condition: 非生産的(振動または要件矛盾) + next: ABORT + - cycle: [ai_fix, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + AI修正 → レビューのサイクルが {cycle_count} 回繰り返されました。 + Report Directory 内のレビューレポート履歴を確認し、収束状況を判断してください。 + + **非生産的の兆候:** + - 同じ finding_id が resolved → new を繰り返している + - 前の修正の副作用で新しい issue が生まれ続けている + - レビュアーの指摘とタスク要件が矛盾しており解消不能 + rules: + - condition: 健全(新しい問題が減少傾向) + next: ai_fix + - condition: 非生産的(振動または要件矛盾) + next: ABORT + - cycle: [supervise_fix, reviewers] + threshold: 3 + judge: + persona: supervisor + instruction_template: | + 監督修正 → レビューのサイクルが {cycle_count} 回繰り返されました。 + Report Directory 内のレビューレポート履歴を確認し、収束状況を判断してください。 + + **非生産的の兆候:** + - 同じ finding_id が resolved → new を繰り返している + - 前の修正の副作用で新しい issue が生まれ続けている + - レビュアーの指摘とタスク要件が矛盾しており解消不能 + rules: + - condition: 健全(新しい問題が減少傾向) + next: supervise_fix + - condition: 非生産的(振動または要件矛盾) + next: ABORT