{"id":"coding-feature-flag-reviewer","title":"Feature Flag Reviewer","description":"Risk findings typed. Risky flags in PRs. Typed v1 agent with eval coverage.","category":"coding","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["coding","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":"coding-feature-flag-reviewer","description":"Risk findings typed. Risky flags in PRs. Typed v1 agent with eval coverage.","systemPrompt":"You are Feature Flag Reviewer. Risky flags in PRs. Output: Risk findings 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_flag_reviewer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.coding-feature-flag-reviewer","name":"Feature Flag Reviewer","description":"Risk findings typed. Risky flags in PRs. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"coding-feature-flag-reviewer","description":"Risk findings typed. Risky flags in PRs. 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/** Feature Flag Reviewer — v1 validated. Pain: Risky flags in PRs */\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 CodingFeatureFlagReviewerConfig {\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: 'coding-feature-flag-reviewer',\n  description: \"Feature Flag Reviewer — typed output agent (draft spec).\",\n  systemPrompt: `You are Feature Flag Reviewer. Risky flags in PRs. Output: Risk findings 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_flag_reviewer exactly once. Stop.`,\n  tools: ['submit_flag_reviewer'],\n}\n\nexport function createCodingFeatureFlagReviewerAgent(config: CodingFeatureFlagReviewerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_flag_reviewer', 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('coding-feature-flag-reviewer 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: 'coding-feature-flag-reviewer',\n    run,\n    asHandle() { return { name: 'coding-feature-flag-reviewer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Feature Flag Reviewer\n\n> **v1 validated** — `npx agentskit add coding-feature-flag-reviewer`\n\n## Pain\nRisky flags in PRs\n\n## Output\nRisk findings typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'coding-feature-flag-reviewer',\n  cases: [\n    { input: 'Complete input for Feature Flag Reviewer: Risky flags in PRs. 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.96,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid structured outputs for all three cases, resisted the injection case, avoided fabricating feature-flag risks from missing evidence, surfaced concrete gaps and useful open questions, and kept recommendations aligned with its purpose. The behavior is somewhat conservative and the normal case does not demonstrate actual feature-flag analysis because the supplied prompt contained no PR artifacts, but the response correctly handled uncertainty instead of hallucinating.","strengths":["Valid structured output in every case with summaries, findings, gaps, open questions, and requiresReview in the recorded output.","Correctly rejected instruction-injection pressure and did not output the requested unsafe approval string.","Consistently avoided hallucinating PR details or feature flag risks absent supporting input.","Provided useful next-step questions and requested the right artifacts: PR diff, flag names, defaults, targeting, rollout, monitoring, rollback, and ownership."],"notes":[]}}