UNPKG

paqad-ai

Version:

Spec-driven development framework — AI agents that think before they type

79 lines (74 loc) • 2.59 kB
import { createRequire as __paqadCreateRequire } from 'module'; const require = __paqadCreateRequire(import.meta.url); import { init_esm_shims } from "./chunk-IDFRWBMN.js"; // src/evidence/ledger.ts init_esm_shims(); import { createHash } from "crypto"; import { appendFileSync, existsSync, mkdirSync, readFileSync } from "fs"; import { dirname, join } from "path"; // src/core/types/evidence-ledger.ts init_esm_shims(); var EVIDENCE_LEDGER_SCHEMA_VERSION = 1; var PAQAD_VSA_PREDICATE_TYPE = "https://paqad.ai/attestations/verification-summary/v1"; var IN_TOTO_STATEMENT_TYPE = "https://in-toto.io/Statement/v1"; // src/evidence/ledger.ts function computeRowContentHash(identity) { const canonical = JSON.stringify([ identity.engine, identity.code, identity.subject_digest, identity.verdict, identity.strength_class ]); return createHash("sha256").update(canonical).digest("hex"); } function buildEvidenceRow(row) { return { schema_version: EVIDENCE_LEDGER_SCHEMA_VERSION, ts: row.ts, engine: row.engine, code: row.code, subject_digest: row.subject_digest, verdict: row.verdict, strength_class: row.strength_class, content_hash: computeRowContentHash(row), ...row.detail !== void 0 ? { detail: row.detail } : {}, ...row.skip_kind !== void 0 && row.verdict === "skipped" ? { skip_kind: row.skip_kind } : {} }; } function readEvidenceRowsAt(projectRoot, relPath) { const path = join(projectRoot, relPath); if (!existsSync(path)) return []; return parseEvidenceRows(readFileSync(path, "utf8")); } function parseEvidenceRows(raw) { const out = []; for (const line of raw.split("\n")) { const trimmed = line.trim(); if (trimmed.length === 0) continue; try { const parsed = JSON.parse(trimmed); if (isEvidenceLedgerRow(parsed)) { out.push( typeof parsed.ts === "string" ? parsed : { ...parsed, ts: parsed.recorded_at } ); } } catch { } } return out; } function isEvidenceLedgerRow(value) { if (typeof value !== "object" || value === null) return false; const row = value; return (typeof row.ts === "string" || typeof row.recorded_at === "string") && typeof row.engine === "string" && typeof row.code === "string" && typeof row.subject_digest === "string" && typeof row.verdict === "string" && typeof row.strength_class === "string" && typeof row.content_hash === "string"; } export { EVIDENCE_LEDGER_SCHEMA_VERSION, PAQAD_VSA_PREDICATE_TYPE, IN_TOTO_STATEMENT_TYPE, buildEvidenceRow, readEvidenceRowsAt, parseEvidenceRows };