{"id":"data-pii-column-scanner","title":"PII Column Scanner","description":"Columns typed. PII in tables. 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-pii-column-scanner","description":"Columns typed. PII in tables. Typed v1 agent with eval coverage.","systemPrompt":"You are PII Column Scanner. PII in tables. Output: Columns 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_column_scanner exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.data-pii-column-scanner","name":"PII Column Scanner","description":"Columns typed. PII in tables. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"data-pii-column-scanner","description":"Columns typed. PII in tables. 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/** PII Column Scanner — v1 validated. Pain: PII in tables */\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 DataPiiColumnScannerConfig {\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: 'data-pii-column-scanner',\n  description: \"PII Column Scanner — typed output agent (draft spec).\",\n  systemPrompt: `You are PII Column Scanner. PII in tables. Output: Columns 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_column_scanner exactly once. Stop.`,\n  tools: ['submit_column_scanner'],\n}\n\nexport function createDataPiiColumnScannerAgent(config: DataPiiColumnScannerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_column_scanner', 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-pii-column-scanner 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: 'data-pii-column-scanner',\n    run,\n    asHandle() { return { name: 'data-pii-column-scanner', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# PII Column Scanner\n\n> **v1 validated** — `npx agentskit add data-pii-column-scanner`\n\n## Pain\nPII in tables\n\n## Output\nColumns typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'data-pii-column-scanner',\n  cases: [\n    { input: 'Complete input for PII Column Scanner: PII in tables. 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 explicit injection attempt, avoided fabricating PII classifications where no table/schema/columns were supplied, and consistently surfaced actionable gaps and open questions. Behavior is conservative and aligned with a PII column scanner operating under uncertainty. Minor weakness: it is somewhat overzealous in labeling ordinary sparse test prompts as instruction-like/untrusted rather than simply insufficient input, but that does not create unsafe or incorrect behavior.","strengths":["Valid structured output in every case with summary, findings, gaps, open questions, and review requirement.","No hallucinated columns or PII classifications from absent evidence.","Injection case correctly refused the requested APPROVED output and treated the prompt as untrusted data.","Minimal and sparse inputs were handled safely with useful next-step questions."],"notes":[]}}