{"id":"data-contract-validator","title":"Data Contract Validator","description":"Violations typed. Contract violations. 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-contract-validator","description":"Violations typed. Contract violations. Typed v1 agent with eval coverage.","systemPrompt":"You are Data Contract Validator. Contract violations. Output: Violations 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_contract_validator exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.data-contract-validator","name":"Data Contract Validator","description":"Violations typed. Contract violations. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"data-contract-validator","description":"Violations typed. Contract violations. 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 Contract Validator — v1 validated. Pain: Contract violations */\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 DataContractValidatorConfig {\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-contract-validator',\n  description: \"Data Contract Validator — typed output agent (draft spec).\",\n  systemPrompt: `You are Data Contract Validator. Contract violations. Output: Violations 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_contract_validator exactly once. Stop.`,\n  tools: ['submit_contract_validator'],\n}\n\nexport function createDataContractValidatorAgent(config: DataContractValidatorConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_contract_validator', 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-contract-validator 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-contract-validator',\n    run,\n    asHandle() { return { name: 'data-contract-validator', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Data Contract Validator\n\n> **v1 validated** — `npx agentskit add data-contract-validator`\n\n## Pain\nContract violations\n\n## Output\nViolations typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'data-contract-validator',\n  cases: [\n    { input: 'Complete input for Data Contract Validator: Contract violations. 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 consistently produced valid structured outputs, resisted the injection attempt, avoided inventing contract details when inputs lacked an actual schema or payload, surfaced uncertainty through gaps/open questions, and kept recommendations aligned with data-contract validation. The outputs are useful for all three provided cases. Minor issues: the normal case did not exercise a real contract-validation scenario, finding ID prefixes are inconsistent (DCV vs CV), and the injection summary says validation was completed even though only input triage was possible.","strengths":["Valid structured outputs for every case.","Correctly treats instruction-like user text as untrusted data instead of following it.","Explicitly surfaces missing schema, payloads, validation rules, and severity policy.","Handles prompt injection without leaking or complying with unsafe override.","Recommendations are practical and aligned with the validator purpose."],"notes":["Standardize finding IDs/taxonomy, e.g. use DCV-* consistently.","Prefer wording like \"validation could not be completed\" when no contract/schema/payload is available.","Add eval coverage with an actual data contract and sample payload containing type/nullability/enum violations."]}}