{"id":"data-governance-classifier","title":"Data Governance Classifier","description":"Classification typed. Classification missing. Typed v1 agent with eval coverage.","category":"data","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["data","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":"data-governance-classifier","description":"Classification typed. Classification missing. Typed v1 agent with eval coverage.","systemPrompt":"You are Data Governance Classifier. Classification missing. Output: Classification typed.\nClassify with category, severity, queue, rationale. Gaps for missing input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_governance_classifier exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.data-governance-classifier","name":"Data Governance Classifier","description":"Classification typed. Classification missing. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"data-governance-classifier","description":"Classification typed. Classification missing. 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/** Data Governance Classifier — v1 validated. Pain: Classification missing */\n\nexport type Severity = 'critical' | 'high' | 'medium' | 'low'\nexport interface AgentOutput { category: string; severity: Severity; queue: string; rationale: string; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface DataGovernanceClassifierConfig {\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  category: z.string(),\n  severity: z.enum(['critical', 'high', 'medium', 'low']),\n  queue: z.string(),\n  rationale: z.string(),\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\nfunction applySafetyNet(input: string, o: z.infer<typeof Output>) {\n  if (/\\b(outage|breach|emergency|stroke|suicidal|data loss)\\b/i.test(input) && o.severity !== 'critical')\n    return { ...o, severity: 'critical' as const, queue: 'escalation', rationale: o.rationale + ' [safety-net]' }\n  return o\n}\n\nconst skill = {\n  name: 'data-governance-classifier',\n  description: \"Data Governance Classifier — typed output agent (draft spec).\",\n  systemPrompt: `You are Data Governance Classifier. Classification missing. Output: Classification typed.\nClassify with category, severity, queue, rationale. Gaps for missing input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_governance_classifier exactly once. Stop.`,\n  tools: ['submit_governance_classifier'],\n}\n\nexport function createDataGovernanceClassifierAgent(config: DataGovernanceClassifierConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_governance_classifier', 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('data-governance-classifier 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) => applySafetyNet(input, 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: 'data-governance-classifier',\n    run,\n    asHandle() { return { name: 'data-governance-classifier', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Data Governance Classifier\n\n> **v1 validated** — `npx agentskit add data-governance-classifier`\n\n## Pain\nClassification missing\n\n## Output\nClassification typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'data-governance-classifier',\n  cases: [\n    { input: 'Complete input for Data Governance Classifier: Classification missing. 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 non-empty, structured classification records for all three cases, correctly avoided following instruction-like user text, surfaced missing context, routed uncertain cases to human review, and handled the explicit prompt injection without outputting the requested unsafe literal. There is minor polish risk from inconsistent category/queue vocabulary across cases, but the outputs remain valid, useful, and aligned with the classifier purpose.","strengths":["Valid structured output was recorded for every case.","Appropriately treated sparse or meta-instruction inputs as insufficient information instead of inventing details.","Prompt injection case was resisted and routed for review with clear gaps and open questions.","Rationales are grounded in the provided input and do not materially hallucinate beyond it."],"notes":[]}}