UNPKG

@blundergoat/goat-flow

Version:

AI coding agent harness and local dashboard for Claude Code, OpenAI Codex, Google Antigravity, and GitHub Copilot - setup audits, guardrails, structured skills, deny hooks, and persistent learning loops.

89 lines 3.71 kB
/** * Evidence-provenance schema for audit checks. * * Co-located with each check's implementation so provenance travels with the * check and can't drift from its source. Defined here as the stable import * path so back-fill work can consume it without redefining. * * Schema adapted from agnix rules.json + rust emission in * `/home/devgoat/projects/goat-flow-related/agnix/crates/agnix-core/`. * * The `"unknown"` source_type + required `reason` field is the critique-locked * escape hatch: existing checks include historical entries that cannot * have their provenance reconstructed. Such checks declare `source_type: * "unknown"` and state the reason (e.g. "pre-dates v1.1.0 cleanup"), * rather than fabricating a citation or stalling the back-fill. */ /** Check that unknown-source evidence includes a reason. */ function checkUnknownReason(evidence) { if (evidence.source_type === "unknown" && (!evidence.reason || evidence.reason.trim() === "")) { return "source_type 'unknown' requires a non-empty `reason` explaining why provenance could not be reconstructed"; } return null; } /** Check that `verified_on` uses YYYY-MM-DD. */ function checkVerifiedOn(evidence) { if (/^\d{4}-\d{2}-\d{2}$/.test(evidence.verified_on)) return null; return `verified_on must be ISO date YYYY-MM-DD, got ${JSON.stringify(evidence.verified_on)}`; } /** * Check that non-unknown provenance has at least one citation channel. * * The separate branches are intentional because legacy checks may cite vendor * URLs, framework files, target-project files, or pre-split evidence_paths; the * validator must preserve all four channels while still blocking uncited norms. */ function checkSourceRequired(evidence) { if (evidence.source_type === "unknown") return null; if (evidence.source_urls.length > 0) return null; if (evidence.evidence_paths && evidence.evidence_paths.length > 0) { return null; } if (evidence.framework_evidence_paths && evidence.framework_evidence_paths.length > 0) { return null; } if (evidence.target_evidence_paths && evidence.target_evidence_paths.length > 0) { return null; } return "non-unknown source_type requires a non-empty source_url, evidence_path, framework_evidence_path, or target_evidence_path"; } /** Check that every evidence path exists. */ function checkEvidencePathsExist(evidence, pathExists) { const paths = [ ...(evidence.evidence_paths ?? []), ...(evidence.framework_evidence_paths ?? []), ...(evidence.target_evidence_paths ?? []), ]; return paths .filter((evidencePath) => !pathExists(evidencePath)) .map((evidencePath) => `evidence_path does not exist: ${evidencePath}`); } /** * Runtime check that a CheckEvidence record satisfies the audit schema. * * @param evidence - Provenance record attached to an audit check or runtime event. * @param pathExists - Optional resolver used by development/preflight checks to reject stale local evidence paths. * @returns Validation errors; an empty array means the record is usable. */ export function validateProvenance(evidence, pathExists) { const errors = []; const unknownErr = checkUnknownReason(evidence); if (unknownErr) errors.push(unknownErr); const dateErr = checkVerifiedOn(evidence); if (dateErr) errors.push(dateErr); const sourceErr = checkSourceRequired(evidence); if (sourceErr) errors.push(sourceErr); if (pathExists) errors.push(...checkEvidencePathsExist(evidence, pathExists)); return errors; } //# sourceMappingURL=provenance-types.js.map