Something went wrong. Try again.
My website. cameron.stream
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202import { createHash } from "node:crypto";import { readFile } from "node:fs/promises";import { resolve } from "node:path";import { knowledgeContentDigest, knowledgeRoute, loadKnowledgeGraph, type KnowledgeEntry,} from "../src/knowledge.ts";import { loadKnowledgePolicy, scanKnowledgeDraft } from "./knowledge-policy.ts";
interface StyleFinding { severity: "review"; code: string; detail: string;}
async function verifyTechnicalAuthorization(entry: KnowledgeEntry): Promise<Array<{ slug: string; severity: "block"; code: string; detail: string;}>> { if (entry.reviewBasis !== "technical-publication-authorization") return []; const authorization = entry.publicationAuthorization; if (!authorization) { return [{ slug: entry.slug, severity: "block", code: "missing-technical-authorization", detail: "technical publication entry has no route-scoped authorization metadata", }]; } try { const receiptBytes = await readFile(resolve(process.cwd(), authorization.receiptPath)); const digest = `sha256:${createHash("sha256").update(receiptBytes).digest("hex")}`; const receipt = JSON.parse(receiptBytes.toString("utf8")) as Record<string, unknown>; const recordedAt = typeof receipt.recordedAt === "string" ? new Date(receipt.recordedAt).toISOString() : undefined; const valid = digest === authorization.receiptDigest && digest === entry.reviewReceiptDigest && receipt.kind === authorization.kind && receipt.entrySlug === entry.slug && receipt.route === knowledgeRoute(entry) && receipt.authorizedBy === authorization.authorizedBy && recordedAt === authorization.recordedAt.toISOString() && receipt.scope === authorization.scope && receipt.exactRenderReviewed === false && receipt.implementationReviewedBy === entry.implementationReviewedBy; return valid ? [] : [{ slug: entry.slug, severity: "block", code: "technical-authorization-receipt-mismatch", detail: "tracked authorization receipt bytes or fields do not match approved frontmatter", }]; } catch (error) { return [{ slug: entry.slug, severity: "block", code: "technical-authorization-receipt-unreadable", detail: error instanceof Error ? error.message : String(error), }]; }}
function scanKnowledgeStyle(entry: Awaited<ReturnType<typeof loadKnowledgeGraph>>["entries"][number]): StyleFinding[] { const findings: StyleFinding[] = []; const body = entry.body.trim(); const referenceLike = entry.kind !== "journal" && entry.kind !== "lesson";
if (entry.kind !== "journal" && /^#{1,6}\s/.test(body)) { findings.push({ severity: "review", code: "missing-standalone-lead", detail: "non-journal page begins with a heading instead of a self-contained prose lead", }); }
const editorialHeadings = [ "Questions to expand", "Why this topic now", "Short version", "Boundary-check note", ]; for (const heading of editorialHeadings) { if (new RegExp(`^#{2,6}\\s+${heading.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}\\s*$`, "im").test(body)) { findings.push({ severity: "review", code: "visible-editorial-scaffolding", detail: `reader-facing editorial heading: ${heading}`, }); } }
const lead = body.split(/^#{2,6}\s/m, 1)[0]; if (referenceLike && /\b(?:I|me|my|mine|we|us|our|ours)\b/i.test(lead)) { findings.push({ severity: "review", code: "first-person-reference-lead", detail: "reference-style lead uses first-person voice; attribute the perspective or use neutral prose", }); }
if ( entry.kind !== "journal" && entry.related.length > 0 && !/\[[^\]]+\]\(\/knowledge\/[a-z0-9-]+(?:\/[a-z0-9-]+)*\)/.test(body) ) { findings.push({ severity: "review", code: "metadata-only-connections", detail: "related Knowledge pages are present only in metadata, with no reader-facing body link", }); }
return findings;}
async function main(): Promise<void> { const includeDrafts = process.argv.includes("--include-drafts"); const graph = await loadKnowledgeGraph({ root: resolve(process.cwd(), "knowledge"), includeDrafts, }); const policy = loadKnowledgePolicy(); const authorizationFindings = (await Promise.all( graph.entries.map((entry) => verifyTechnicalAuthorization(entry)), )).flat(); const findings = [...authorizationFindings, ...graph.entries.flatMap((entry) => { const entryFindings = scanKnowledgeDraft(entry.body, policy).map((finding) => ({ slug: entry.slug, ...finding, })); entryFindings.push(...scanKnowledgeStyle(entry).map((finding) => ({ slug: entry.slug, ...finding, })));
const contentDigest = knowledgeContentDigest(entry); if (!entry.draft && entry.reviewedContentDigest !== contentDigest) { entryFindings.push({ slug: entry.slug, severity: "block", code: "reviewed-content-digest-mismatch", detail: "published Markdown no longer matches the content digest reviewed for release", }); }
if (entry.kind === "person" && !policy.allowedPeopleSlugs.includes(entry.slug)) { entryFindings.push({ slug: entry.slug, severity: "block", code: "unapproved-person-entry", detail: "person slug is not explicitly allowlisted", }); } if (entry.kind === "person" && entry.claimMode !== "factual") { entryFindings.push({ slug: entry.slug, severity: "block", code: "person-entry-mode", detail: "person entries must remain factual", }); } const hasReaderFacingLink = /\[[^\]]+\]\((?:https?:\/\/|\/)[^)]+\)/.test(entry.body) || entry.sources.length > 0 || entry.related.length > 0 || entry.backlinks.length > 0; if (!hasReaderFacingLink) { entryFindings.push({ slug: entry.slug, severity: "block", code: "zero-link-entry", detail: "entry has no inline, source, related, or backlink path for readers", }); }
return entryFindings; })]; const blocking = findings.filter((finding) => finding.severity === "block"); const contentDigests = Object.fromEntries( graph.entries.map((entry) => [entry.slug, knowledgeContentDigest(entry)]), );
console.log(JSON.stringify({ entries: graph.entries.length, drafts: graph.entries.filter((entry) => entry.draft).length, published: graph.entries.filter((entry) => !entry.draft).length, graphErrors: graph.errors, findings, contentDigests, }, null, 2));
if (graph.errors.length > 0 || blocking.length > 0) process.exit(1);}
main().catch((error) => { console.error(error); process.exit(1);});