MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / buildAuditPdfBlocks

Function buildAuditPdfBlocks

src/cli/maintain-audit.ts:164–189  ·  view source on GitHub ↗
(log: SignedAuditLog, verdict: AuditVerifyResult)

Source from the content-addressed store, hash-verified

162 * Feed the blocks to pdf-lite's buildPdf. PURE (pass the verdict computed by verifyAuditLog).
163 */
164export function buildAuditPdfBlocks(log: SignedAuditLog, verdict: AuditVerifyResult): import('./pdf-lite.js').PdfBlock[] {
165 const kv = (k: string, v: string): import('./pdf-lite.js').PdfBlock => ({ text: `${k}: ${v}`, size: 10, indent: 10 });
166 const sigLine = !verdict.signaturePresent ? 'unsigned (integrity only)'
167 : verdict.signatureValid === undefined ? `signed (keyId ${log.keyId ?? '?'}) — no key supplied to verify`
168 : verdict.signatureValid ? `VALID — HMAC-SHA256, keyId ${log.keyId ?? '?'} (authentic)` : 'INVALID — wrong key or forged';
169 const blocks: import('./pdf-lite.js').PdfBlock[] = [
170 { text: 'Maintain Audit Log', size: 18, bold: true },
171 { text: `Exported ${log.exportedAt} - ${log.count} run(s) - tamper-evident hash chain (each entry commits to the previous; altering, reordering, or dropping any entry breaks every downstream hash).`, size: 9, spaceBefore: 4 },
172 { text: 'Verification', size: 13, bold: true, spaceBefore: 12 },
173 kv('Chain integrity', verdict.chainValid ? 'INTACT — no entry altered, reordered, or dropped' : `BROKEN at #${verdict.brokenAt} — ${verdict.reason}`),
174 kv('Head', `${verdict.headMatches ? 'matches the chain' : 'MISMATCH'} (${log.head.slice(0, 24)}...)`),
175 kv('Signature', sigLine),
176 kv('Overall', verdict.ok ? 'PASS — this log is trustworthy' : 'FAIL — do not trust this log'),
177 { text: 'Run chain (oldest first)', size: 13, bold: true, spaceBefore: 12 },
178 ];
179 if (!log.entries.length) blocks.push({ text: 'no runs recorded', size: 10, indent: 10 });
180 for (const e of log.entries) {
181 const outcome = e.status === 'opened' ? '[OK] opened' : e.status === 'blocked' ? '[BLOCKED]' : e.status;
182 const checks = e.verification.length ? ` - checks: ${e.verification.map(v => `${v.passed ? 'v' : 'x'} ${v.command}`).join(', ')}` : '';
183 const files = e.filesChanged ? ` - ${e.filesChanged} file(s)` : '';
184 blocks.push({ text: `#${e.seq} ${e.at.slice(0, 10)} ${e.scope} ${outcome}${files}${checks}`, size: 9, mono: true, indent: 10 });
185 if (e.prUrl) blocks.push({ text: ` PR: ${e.prUrl}`, size: 8, mono: true, indent: 10 });
186 }
187 blocks.push({ text: 'Verify this log offline anytime: qodex maintain-audit-verify <file> (exit 1 on tamper - CI-friendly).', size: 8, spaceBefore: 12 });
188 return blocks;
189}
190
191/**
192 * Full audit verification of a parsed log: chain integrity, that the stored head matches the chain,

Callers 2

index.tsFile · 0.85

Calls 2

kvFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected