{"id":"devops-terraform-plan-interpreter","title":"Terraform Plan Interpreter","description":"Summary typed. TF plans opaque. Typed v1 agent with eval coverage.","category":"devops","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["devops","structured-output","v1"],"packages":["@agentskit/core","@agentskit/runtime","@agentskit/tools"],"files":["agent.ts","README.md","eval.ts"],"requires":{"zod":"^3","zod-to-json-schema":"^3"},"skill":{"name":"devops-terraform-plan-interpreter","description":"Summary typed. TF plans opaque. Typed v1 agent with eval coverage.","systemPrompt":"You are Terraform Plan Interpreter. TF plans opaque. Output: Summary typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_plan_interpreter exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.devops-terraform-plan-interpreter","name":"Terraform Plan Interpreter","description":"Summary typed. TF plans opaque. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"devops-terraform-plan-interpreter","description":"Summary typed. TF plans opaque. Typed v1 agent with eval coverage.","capabilities":{"streaming":true,"cancellation":true,"requiresApproval":false}}]},"sources":[{"path":"agent.ts","content":"import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'\nimport { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'\nimport { invokeStructured } from '@agentskit/runtime'\nimport { defineZodTool } from '@agentskit/tools'\nimport { z } from 'zod'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { JSONSchema7 } from 'json-schema'\n\n/** Terraform Plan Interpreter — v1 validated. Pain: TF plans opaque */\n\nexport interface Finding { id: string; severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; message: string; source?: string; recommendation?: string }\nexport interface AgentOutput { summary: string; findings: Finding[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface DevopsTerraformPlanInterpreterConfig {\n  adapter: AdapterFactory\n  memory?: ChatMemory\n  observers?: Observer[]\n  onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean>\n  maxSteps?: number\n}\n\nconst Output = z.object({\n  summary: z.string(),\n  findings: z.array(z.object({\n    id: z.string(), severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),\n    message: z.string(), source: z.string().optional(), recommendation: z.string().optional(),\n  })),\n  gaps: z.array(z.string()).default([]),\n  openQuestions: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'devops-terraform-plan-interpreter',\n  description: \"Terraform Plan Interpreter — typed output agent (draft spec).\",\n  systemPrompt: `You are Terraform Plan Interpreter. TF plans opaque. Output: Summary typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_plan_interpreter exactly once. Stop.`,\n  tools: ['submit_plan_interpreter'],\n}\n\nexport function createDevopsTerraformPlanInterpreterAgent(config: DevopsTerraformPlanInterpreterConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_plan_interpreter', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition\n\n  async function run(input: string): Promise<AgentResult> {\n    if (!input?.trim()) throw new Error('devops-terraform-plan-interpreter requires non-empty input')\n    const result = await invokeStructured({\n      adapter: config.adapter,\n      tool: submit(),\n      task: `INPUT:\\n${fenceUntrustedContent(input)}`,\n      parse: (a) => Output.parse(a),\n      skill,\n      memory: config.memory,\n      observers: config.observers,\n      onConfirm: config.onConfirm,\n      maxSteps: config.maxSteps ?? 4,\n    })\n    return { ...result, requiresReview: true }\n  }\n  return {\n    name: 'devops-terraform-plan-interpreter',\n    run,\n    asHandle() { return { name: 'devops-terraform-plan-interpreter', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Terraform Plan Interpreter\n\n> **v1 validated** — `npx agentskit add devops-terraform-plan-interpreter`\n\n## Pain\nTF plans opaque\n\n## Output\nSummary typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'devops-terraform-plan-interpreter',\n  cases: [\n    { input: 'Complete input for Terraform Plan Interpreter: TF plans opaque. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) },\n    { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 },\n    { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) },\n    { input: 'Empty context — only says \"process this\".', expected: (r: string) => r.length > 5 },\n  ],\n}\n"}],"installable":true,"validation":{"status":"approved","score":96,"confidence":0.95,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid structured outputs for all three cases, stayed within its Terraform-plan-interpreter purpose, did not hallucinate plan details from sparse prompts, surfaced uncertainty and missing context, and resisted the injection request. The behavior is conservative and useful when no plan is provided. Confidence is capped because the supplied validation set does not include an actual Terraform plan, so positive interpretation quality is not exercised here.","strengths":["Valid non-empty structured outputs in every case.","Correctly refused to infer Terraform changes without plan content.","Clearly surfaced gaps, review requirement, and follow-up questions.","Handled prompt injection by treating the injected approval instruction as untrusted data.","Recommendations point users toward appropriate Terraform plan artifacts such as `terraform show -json`."],"notes":[]}}