327 lines
16 KiB
JavaScript
327 lines
16 KiB
JavaScript
const pptxgen = require("pptxgenjs");
|
|
const pptx = new pptxgen();
|
|
|
|
pptx.defineLayout({ name: "CASAN_WIDE", width: 10, height: 5.625 });
|
|
pptx.layout = "CASAN_WIDE";
|
|
pptx.author = "FPT Software AI CoE";
|
|
pptx.company = "FPT Software";
|
|
pptx.subject = "HarnessAthon CASAN Level 5 Demo";
|
|
pptx.title = "HarnessAthon CASAN Level 5 Demo";
|
|
pptx.lang = "en-US";
|
|
pptx.theme = {
|
|
headFontFace: "Aptos Display",
|
|
bodyFontFace: "Aptos",
|
|
lang: "en-US"
|
|
};
|
|
|
|
const theme = {
|
|
primary: "0A0A0A",
|
|
secondary: "404040",
|
|
accent: "0070F3",
|
|
gold: "D4AF37",
|
|
light: "F5F5F5",
|
|
bg: "FFFFFF",
|
|
dark: "141414",
|
|
danger: "D90429",
|
|
success: "0F766E"
|
|
};
|
|
|
|
const W = 10;
|
|
const H = 5.625;
|
|
|
|
function addBadge(slide, n) {
|
|
slide.addShape(pptx.ShapeType.ellipse, {
|
|
x: 9.35, y: 5.13, w: 0.34, h: 0.34,
|
|
fill: { color: theme.primary },
|
|
line: { color: theme.primary }
|
|
});
|
|
slide.addText(String(n).padStart(2, "0"), {
|
|
x: 9.35, y: 5.18, w: 0.34, h: 0.18,
|
|
fontSize: 8, color: "FFFFFF", align: "center",
|
|
fontFace: "Aptos", margin: 0
|
|
});
|
|
}
|
|
|
|
function title(slide, text, subtitle) {
|
|
slide.addText(text, {
|
|
x: 0.52, y: 0.35, w: 7.8, h: 0.42,
|
|
fontSize: 25, bold: true, color: theme.primary,
|
|
fontFace: "Aptos Display", margin: 0, fit: "shrink"
|
|
});
|
|
if (subtitle) {
|
|
slide.addText(subtitle, {
|
|
x: 0.54, y: 0.82, w: 8.4, h: 0.28,
|
|
fontSize: 10.5, color: theme.secondary,
|
|
fontFace: "Aptos", margin: 0, fit: "shrink"
|
|
});
|
|
}
|
|
}
|
|
|
|
function footer(slide) {
|
|
slide.addText("HarnessAthon | CASAN Evidence Package", {
|
|
x: 0.52, y: 5.18, w: 4.8, h: 0.16,
|
|
fontSize: 7.5, color: "737373", margin: 0
|
|
});
|
|
}
|
|
|
|
function card(slide, x, y, w, h, header, body, accent = theme.accent) {
|
|
slide.addShape(pptx.ShapeType.roundRect, {
|
|
x, y, w, h,
|
|
rectRadius: 0.08,
|
|
fill: { color: "FFFFFF" },
|
|
line: { color: "D4D4D4", transparency: 10 }
|
|
});
|
|
slide.addShape(pptx.ShapeType.rect, {
|
|
x, y, w: 0.07, h,
|
|
fill: { color: accent },
|
|
line: { color: accent }
|
|
});
|
|
slide.addText(header, {
|
|
x: x + 0.18, y: y + 0.14, w: w - 0.32, h: 0.26,
|
|
fontSize: 12.5, bold: true, color: theme.primary, margin: 0, fit: "shrink"
|
|
});
|
|
slide.addText(body, {
|
|
x: x + 0.18, y: y + 0.48, w: w - 0.32, h: h - 0.58,
|
|
fontSize: 9.2, color: theme.secondary, margin: 0.02,
|
|
breakLine: false, fit: "shrink"
|
|
});
|
|
}
|
|
|
|
function metric(slide, x, y, label, value, color = theme.accent) {
|
|
slide.addText(value, {
|
|
x, y, w: 1.35, h: 0.42,
|
|
fontSize: 25, bold: true, color, margin: 0,
|
|
align: "center", fit: "shrink"
|
|
});
|
|
slide.addText(label, {
|
|
x: x - 0.1, y: y + 0.48, w: 1.55, h: 0.28,
|
|
fontSize: 8.2, color: theme.secondary, margin: 0,
|
|
align: "center", fit: "shrink"
|
|
});
|
|
}
|
|
|
|
function addScoreBar(slide, x, y, label, from, to, color) {
|
|
slide.addText(label, { x, y, w: 1.55, h: 0.18, fontSize: 8.5, color: theme.primary, margin: 0 });
|
|
slide.addShape(pptx.ShapeType.rect, { x: x + 1.7, y: y + 0.03, w: 2.4, h: 0.11, fill: { color: "E5E5E5" }, line: { color: "E5E5E5" } });
|
|
slide.addShape(pptx.ShapeType.rect, { x: x + 1.7, y: y + 0.03, w: 2.4 * to / 100, h: 0.11, fill: { color }, line: { color } });
|
|
slide.addText(`${from} -> ${to}`, { x: x + 4.25, y: y - 0.02, w: 0.75, h: 0.18, fontSize: 8.2, color: theme.secondary, margin: 0 });
|
|
}
|
|
|
|
function baseSlide(n) {
|
|
const slide = pptx.addSlide();
|
|
slide.background = { color: theme.bg };
|
|
slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: W, h: 0.08, fill: { color: theme.gold }, line: { color: theme.gold } });
|
|
if (n > 1) {
|
|
addBadge(slide, n);
|
|
footer(slide);
|
|
}
|
|
return slide;
|
|
}
|
|
|
|
// 1 Cover
|
|
{
|
|
const slide = baseSlide(1);
|
|
slide.background = { color: theme.dark };
|
|
slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: W, h: H, fill: { color: theme.dark }, line: { color: theme.dark } });
|
|
slide.addShape(pptx.ShapeType.rect, { x: 6.6, y: 0, w: 3.4, h: H, fill: { color: theme.accent, transparency: 4 }, line: { color: theme.accent, transparency: 100 } });
|
|
slide.addText("HARNESSATHON", { x: 0.55, y: 0.55, w: 3.6, h: 0.28, fontSize: 12, color: theme.gold, bold: true, margin: 0 });
|
|
slide.addText("CASAN Level 5 Demo", { x: 0.55, y: 1.25, w: 5.9, h: 0.75, fontSize: 34, bold: true, color: "FFFFFF", margin: 0, fit: "shrink" });
|
|
slide.addText("From Level 4 achieved to Level 5 demonstrated with executable, auditable, measurable harness controls.", {
|
|
x: 0.58, y: 2.15, w: 5.6, h: 0.72, fontSize: 15.5, color: "E5E5E5", margin: 0.02, fit: "shrink"
|
|
});
|
|
card(slide, 6.95, 1.03, 2.25, 0.82, "H4 Security", "Prompt injection block\nPII + secret filtering", theme.gold);
|
|
card(slide, 6.95, 2.08, 2.25, 0.82, "H5 Governance", "Risk approval\nSigned policy bundle", theme.gold);
|
|
card(slide, 6.95, 3.13, 2.25, 0.82, "H6 AgentOps", "Cost, latency, alerts\nCentral dashboard", theme.gold);
|
|
slide.addText("FPT Software AI CoE", { x: 0.58, y: 4.95, w: 2.6, h: 0.18, fontSize: 9, color: "BDBDBD", margin: 0 });
|
|
}
|
|
|
|
// 2 Agenda
|
|
{
|
|
const slide = baseSlide(2);
|
|
title(slide, "What the Judges Should See", "A compact map from baseline gaps to executable evidence.");
|
|
const items = [
|
|
["01", "Baseline", "Why Level 3 -> 4 was the starting point"],
|
|
["02", "Runtime Harness", "How H4/H5/H6 now gate every step"],
|
|
["03", "Evidence", "What can be verified from logs and tests"],
|
|
["04", "Level 5", "What is demonstrated and what remains external"]
|
|
];
|
|
items.forEach((it, i) => {
|
|
const x = 0.7 + (i % 2) * 4.45;
|
|
const y = 1.45 + Math.floor(i / 2) * 1.55;
|
|
slide.addText(it[0], { x, y, w: 0.72, h: 0.48, fontSize: 22, bold: true, color: theme.gold, margin: 0 });
|
|
slide.addText(it[1], { x: x + 0.82, y: y + 0.03, w: 2.2, h: 0.28, fontSize: 16, bold: true, color: theme.primary, margin: 0 });
|
|
slide.addText(it[2], { x: x + 0.82, y: y + 0.45, w: 3.2, h: 0.28, fontSize: 9.5, color: theme.secondary, margin: 0 });
|
|
});
|
|
}
|
|
|
|
// 3 Baseline
|
|
{
|
|
const slide = baseSlide(3);
|
|
title(slide, "Baseline: Strong Engine, Weak Control Layer", "Original assessment had H1/H3/H7 strong, but H4/H5/H6 blocked a confident Level 4 claim.");
|
|
card(slide, 0.6, 1.25, 2.2, 1.05, "Security Gap", "No prompt injection scan\nNo secret/PII gate\nNo output filtering", theme.danger);
|
|
card(slide, 3.1, 1.25, 2.2, 1.05, "Governance Gap", "No approval workflow\nAudit was not tamper-evident\nNo enforced risk registry", theme.danger);
|
|
card(slide, 5.6, 1.25, 2.2, 1.05, "AgentOps Gap", "No cost/token tracking\nNo failure alert\nNo drift signal", theme.danger);
|
|
metric(slide, 7.98, 1.28, "Baseline Avg", "57.9", theme.danger);
|
|
addScoreBar(slide, 0.72, 3.1, "H4 Security", 20, 84, theme.accent);
|
|
addScoreBar(slide, 0.72, 3.55, "H5 Governance", 25, 82, theme.accent);
|
|
addScoreBar(slide, 0.72, 4.0, "H6 AgentOps", 30, 83, theme.accent);
|
|
addScoreBar(slide, 0.72, 4.45, "Average", 58, 87, theme.gold);
|
|
}
|
|
|
|
// 4 Architecture
|
|
{
|
|
const slide = baseSlide(4);
|
|
title(slide, "New Architecture: Harness Around Every Step", "H4/H5/H6 are no longer documents; they are mandatory runtime gates.");
|
|
const stages = [
|
|
["Input", "User or agent payload"],
|
|
["H4", "Security scan"],
|
|
["H5", "Risk + approval"],
|
|
["Agent", "Real execution"],
|
|
["H6", "Metrics + alert"],
|
|
["H4", "Output filter"],
|
|
["Evidence", "Trace + audit"]
|
|
];
|
|
stages.forEach((s, i) => {
|
|
const x = 0.45 + i * 1.32;
|
|
const color = i === 0 || i === 6 ? theme.primary : (i === 3 ? theme.gold : theme.accent);
|
|
slide.addShape(pptx.ShapeType.roundRect, { x, y: 2.05, w: 1.02, h: 0.75, rectRadius: 0.08, fill: { color }, line: { color } });
|
|
slide.addText(s[0], { x: x + 0.05, y: 2.24, w: 0.92, h: 0.18, fontSize: 12, bold: true, color: "FFFFFF", align: "center", margin: 0 });
|
|
slide.addText(s[1], { x: x - 0.04, y: 2.93, w: 1.1, h: 0.36, fontSize: 7.5, color: theme.secondary, align: "center", margin: 0 });
|
|
if (i < stages.length - 1) {
|
|
slide.addText(">", { x: x + 1.1, y: 2.25, w: 0.18, h: 0.2, fontSize: 13, bold: true, color: theme.secondary, margin: 0 });
|
|
}
|
|
});
|
|
card(slide, 0.75, 3.85, 2.55, 0.75, "Boss Integration", "okr.bossbuiltin mandates CASAN protocol before every delegated step.", theme.gold);
|
|
card(slide, 3.75, 3.85, 2.55, 0.75, "Pipeline Context", "Demo context maps Steps 0-13 to H4/H5/H6 traces.", theme.gold);
|
|
card(slide, 6.75, 3.85, 2.55, 0.75, "Evidence First", "Every claim links to executable tests and generated artifacts.", theme.gold);
|
|
}
|
|
|
|
// 5 H4
|
|
{
|
|
const slide = baseSlide(5);
|
|
title(slide, "H4 Security Harness", "Fail closed before LLM/tool execution and filter generated output afterwards.");
|
|
card(slide, 0.65, 1.25, 2.35, 1.05, "Input Gate", "Blocks prompt injection\nBlocks critical secrets\nMasks email, phone, ID", theme.accent);
|
|
card(slide, 3.25, 1.25, 2.35, 1.05, "Output Gate", "Redacts secrets\nMasks PII again\nFlags uncertainty language", theme.accent);
|
|
card(slide, 5.85, 1.25, 2.35, 1.05, "Evidence", "security-*.json\nsecurity.jsonl\nattack + PII test files", theme.gold);
|
|
slide.addText("Verification highlights", { x: 0.7, y: 3.05, w: 2.2, h: 0.28, fontSize: 16, bold: true, color: theme.primary, margin: 0 });
|
|
slide.addText("PASS: H4 blocks prompt injection\nPASS: PII output contains ***MASKED_EMAIL***\nPASS: PII output contains ***MASKED_PHONE***", {
|
|
x: 0.7, y: 3.55, w: 7.9, h: 0.72, fontSize: 11, color: theme.secondary, margin: 0.02, fit: "shrink"
|
|
});
|
|
}
|
|
|
|
// 6 H5
|
|
{
|
|
const slide = baseSlide(6);
|
|
title(slide, "H5 Governance Harness", "High-risk actions are denied by default and every decision is tamper-evident.");
|
|
card(slide, 0.6, 1.22, 2.1, 1.1, "Risk Scoring", "Action type + content\nLow / medium / high\nDeploy and secrets are high", theme.accent);
|
|
card(slide, 2.95, 1.22, 2.1, 1.1, "Approval", "Non-interactive\nApprover identity required\nDeny by default", theme.accent);
|
|
card(slide, 5.3, 1.22, 2.1, 1.1, "Audit Chain", "previous_record_hash\nrecord_hash\nVerifier script", theme.gold);
|
|
metric(slide, 7.75, 1.35, "Governance Score", "87", theme.gold);
|
|
slide.addText("Proof points", { x: 0.72, y: 3.08, w: 1.8, h: 0.3, fontSize: 15, bold: true, color: theme.primary, margin: 0 });
|
|
slide.addText("High-risk deploy without idempotency: denied\nHigh-risk deploy with approver: approved\nAudit chain verification: POLICY + AUDIT valid", {
|
|
x: 0.72, y: 3.55, w: 8.2, h: 0.7, fontSize: 11, color: theme.secondary, margin: 0.02
|
|
});
|
|
}
|
|
|
|
// 7 H6
|
|
{
|
|
const slide = baseSlide(7);
|
|
title(slide, "H6 AgentOps Harness", "Every run becomes observable: status, latency, token, cost, retry, alerts.");
|
|
metric(slide, 0.9, 1.35, "Trace JSON", "10", theme.accent);
|
|
metric(slide, 2.55, 1.35, "Failure Alerts", "1+", theme.danger);
|
|
metric(slide, 4.2, 1.35, "Provider Telemetry", "on", theme.gold);
|
|
metric(slide, 5.85, 1.35, "Dashboard", "on", theme.success);
|
|
card(slide, 0.72, 3.0, 2.6, 0.92, "Metrics JSONL", "latency_ms, cost_estimate, total_tokens, status, alerts", theme.accent);
|
|
card(slide, 3.65, 3.0, 2.6, 0.92, "Provider Usage", "sample-provider record imported into provider-usage.jsonl", theme.gold);
|
|
card(slide, 6.58, 3.0, 2.6, 0.92, "Central Dashboard", "Aggregates metrics, fallback, tools, provider usage, projects", theme.success);
|
|
}
|
|
|
|
// 8 Level 5
|
|
{
|
|
const slide = baseSlide(8);
|
|
title(slide, "Level 5 Mechanisms Demonstrated", "The package includes local, verifiable implementations for the main Level 5 controls.");
|
|
const rows = [
|
|
["Drift", "Golden run comparison"],
|
|
["Fallback", "Primary fail -> fallback route"],
|
|
["Tool Registry", "Owner, risk, idempotency"],
|
|
["Rollback", "Transaction record + execute"],
|
|
["KPI Feedback", "Business outcome report"],
|
|
["Signed Policy", "Manifest + public verify"],
|
|
["Reuse", "Shared harness registry"],
|
|
["Dashboard", "Central AgentOps HTML"]
|
|
];
|
|
rows.forEach((r, i) => {
|
|
const x = 0.55 + (i % 4) * 2.35;
|
|
const y = 1.25 + Math.floor(i / 4) * 1.42;
|
|
card(slide, x, y, 2.05, 0.82, r[0], r[1], i % 2 ? theme.gold : theme.accent);
|
|
});
|
|
slide.addText("Positioning: Level 4 achieved; Level 5 demonstrated locally with clear production integration boundary.", {
|
|
x: 0.7, y: 4.45, w: 8.5, h: 0.28, fontSize: 11, color: theme.primary, bold: true, margin: 0
|
|
});
|
|
}
|
|
|
|
// 9 Evidence
|
|
{
|
|
const slide = baseSlide(9);
|
|
title(slide, "Evidence Map", "The strongest part of the submission is that each claim has a file path.");
|
|
const evidence = [
|
|
["Injection blocked", "01-security-attack.stderr"],
|
|
["Audit valid", "06b-audit-chain.stdout"],
|
|
["13-step context", "pipeline-context.yaml"],
|
|
["Policy signed", "policy-manifest.sig"],
|
|
["Provider usage", "provider-usage.jsonl"],
|
|
["Harness reuse", "project-registry.json"]
|
|
];
|
|
evidence.forEach((e, i) => {
|
|
const y = 1.2 + i * 0.55;
|
|
slide.addShape(pptx.ShapeType.rect, { x: 0.75, y: y + 0.04, w: 0.12, h: 0.12, fill: { color: theme.gold }, line: { color: theme.gold } });
|
|
slide.addText(e[0], { x: 1.0, y, w: 2.4, h: 0.2, fontSize: 10.5, bold: true, color: theme.primary, margin: 0 });
|
|
slide.addText(e[1], { x: 3.05, y, w: 5.5, h: 0.2, fontSize: 9.5, color: theme.secondary, margin: 0 });
|
|
});
|
|
card(slide, 6.55, 3.85, 2.55, 0.72, "Run It Live", "bash .specify/tests/run-casan4-harness-tests.sh", theme.success);
|
|
}
|
|
|
|
// 10 Dashboard
|
|
{
|
|
const slide = baseSlide(10);
|
|
title(slide, "Central AgentOps Dashboard", "A static dashboard proves the aggregation shape for Level 5 operations.");
|
|
card(slide, 0.65, 1.18, 2.35, 1.02, "Aggregates", "H6 run metrics\nProvider telemetry\nFallback route records", theme.accent);
|
|
card(slide, 3.3, 1.18, 2.35, 1.02, "Governance Signals", "Tool denials\nRegistered projects\nPolicy verification", theme.gold);
|
|
card(slide, 5.95, 1.18, 2.35, 1.02, "Production Path", "Replace static HTML with hosted dashboard and live data ingestion", theme.success);
|
|
slide.addShape(pptx.ShapeType.rect, { x: 0.85, y: 3.0, w: 7.95, h: 0.55, fill: { color: "F5F5F5" }, line: { color: "D4D4D4" } });
|
|
slide.addText("central-agentops-dashboard.html", { x: 1.05, y: 3.18, w: 3.2, h: 0.18, fontSize: 10.5, bold: true, color: theme.primary, margin: 0 });
|
|
slide.addText("Cost | Latency | Failures | Fallback | Provider Tokens | Registered Projects", {
|
|
x: 1.05, y: 3.68, w: 7.2, h: 0.3, fontSize: 12, color: theme.secondary, margin: 0
|
|
});
|
|
}
|
|
|
|
// 11 Score
|
|
{
|
|
const slide = baseSlide(11);
|
|
title(slide, "Score and Claim Boundary", "Strong enough for competition; honest enough for production review.");
|
|
metric(slide, 0.88, 1.35, "Level 4 Score", "88.7", theme.accent);
|
|
metric(slide, 2.55, 1.35, "Level 5 Demo", "86", theme.gold);
|
|
metric(slide, 4.2, 1.35, "Tests", "PASS", theme.success);
|
|
card(slide, 0.75, 3.0, 2.65, 0.95, "Claim", "Level 4 achieved.\nLevel 5 demonstrated locally.", theme.success);
|
|
card(slide, 3.65, 3.0, 2.65, 0.95, "Boundary", "Enterprise production requires IdP, WORM logs, live provider APIs, hosted dashboard.", theme.gold);
|
|
card(slide, 6.55, 3.0, 2.65, 0.95, "Why It Matters", "Harness is executable, auditable, measurable, and testable.", theme.accent);
|
|
}
|
|
|
|
// 12 Close
|
|
{
|
|
const slide = baseSlide(12);
|
|
slide.background = { color: theme.dark };
|
|
slide.addShape(pptx.ShapeType.rect, { x: 0, y: 0, w: W, h: H, fill: { color: theme.dark }, line: { color: theme.dark } });
|
|
addBadge(slide, 12);
|
|
slide.addText("Ready for Review", { x: 0.75, y: 1.0, w: 5.8, h: 0.65, fontSize: 36, bold: true, color: "FFFFFF", margin: 0 });
|
|
slide.addText("The control layer is now executable. The evidence is reproducible. The boundary is explicit.", {
|
|
x: 0.78, y: 1.88, w: 6.6, h: 0.55, fontSize: 16, color: "E5E5E5", margin: 0.02
|
|
});
|
|
card(slide, 0.9, 3.25, 2.3, 0.72, "Verify", "Run harness tests", theme.gold);
|
|
card(slide, 3.55, 3.25, 2.3, 0.72, "Inspect", "Open evidence map", theme.gold);
|
|
card(slide, 6.2, 3.25, 2.3, 0.72, "Challenge", "Use Q&A file", theme.gold);
|
|
slide.addText("Thank you", { x: 0.78, y: 4.95, w: 1.4, h: 0.18, fontSize: 9, color: "BDBDBD", margin: 0 });
|
|
}
|
|
|
|
pptx.writeFile({ fileName: "../HarnessAthon_CASAN_Level5_Demo.pptx" });
|