Files
CASAN/00_SUBMISSION_PACKAGE/presentation/slides/compile.js
T
2026-06-30 02:21:39 +09:00

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" });