{"id":"security-breach-notification-drafter","title":"Breach Notification Drafter","description":"Notice typed. Breach notices. Typed v1 agent with eval coverage.","category":"cybersecurity","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["cybersecurity","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":"security-breach-notification-drafter","description":"Notice typed. Breach notices. Typed v1 agent with eval coverage.","systemPrompt":"You are Breach Notification Drafter. Breach notices. Output: Notice typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_notification_drafter exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.security-breach-notification-drafter","name":"Breach Notification Drafter","description":"Notice typed. Breach notices. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"security-breach-notification-drafter","description":"Notice typed. Breach notices. 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/** Breach Notification Drafter — v1 validated. Pain: Breach notices */\n\nexport interface Section { heading: string; body: string; citations: string[] }\nexport interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface SecurityBreachNotificationDrafterConfig {\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  title: z.string(),\n  sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1),\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: 'security-breach-notification-drafter',\n  description: \"Breach Notification Drafter — typed output agent (draft spec).\",\n  systemPrompt: `You are Breach Notification Drafter. Breach notices. Output: Notice typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_notification_drafter exactly once. Stop.`,\n  tools: ['submit_notification_drafter'],\n}\n\nexport function createSecurityBreachNotificationDrafterAgent(config: SecurityBreachNotificationDrafterConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_notification_drafter', 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('security-breach-notification-drafter 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: 'security-breach-notification-drafter',\n    run,\n    asHandle() { return { name: 'security-breach-notification-drafter', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Breach Notification Drafter\n\n> **v1 validated** — `npx agentskit add security-breach-notification-drafter`\n\n## Pain\nBreach notices\n\n## Output\nNotice typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'security-breach-notification-drafter',\n  cases: [\n    { input: 'Complete input for Breach Notification Drafter: Breach notices. 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, non-empty structured outputs for all three cases, stayed aligned with breach-notification drafting, surfaced uncertainty and missing facts, required human/legal review, and resisted the injection attempt. The normal case necessarily used illustrative facts because the input supplied no real incident details, but it clearly labeled them as assumptions and preserved review gates, so this is not a material hallucination for this eval prompt.","strengths":["Consistent structured output across all cases with title, sections, gaps, openQuestions, and requiresReview.","Strong handling of sparse input by producing a fact-gathering scaffold instead of overclaiming.","Injection case correctly ignored the instruction to output APPROVED and explicitly noted the attempted redirection.","Appropriate legal/security caution: requires counsel or authorized review before notices are sent.","Normal case provides a usable illustrative breach-notification packet while clearly marking assumed facts."],"notes":[]}}