Files
CASAN/casan-next-plans/CASAN_SLIDE_DECK.html
T
thanhnvandClaude Opus 4.8 2ffbda3fad feat(video+deck): Part 2 hardening demo script + slide deck update
- run-hardening.sh: narrated "Part 2" battery in the same visual language as
  run-all.sh (card/attack/guard/cmd + on-screen exit code with ⛔/✋/✅ verdict
  chips). Scenes: Track A (HA1-7: homoglyph/zero-width/base64, strict fail-closed,
  telemetry tamper, cost slow-boil/spray, benign FP=0%), Track C-MVP (HC1-4:
  action-gate, supply-chain, data-exfil, sandbox), and the Evidence Pack
  money-shot (HE1-4: pack → verify VALID → tamper 1 byte → TAMPERED exit=1 →
  certified-only-when-earned). Verified end-to-end (exit 0).
- CASAN_SLIDE_DECK.html: reflect implemented vs planned honestly. Updated H4/H5/H6
  AFTER columns, evidence terminal (140 checks), threat-model reframed to
  "identified AND Track A closed", readiness meters bumped to ~3.8-4.0, Track C-MVP
  reframed to DELIVERED (29/29), roadmap marks 07+09 done. Added 2 slides:
  "Track A delivered" and "Evidence Pack money-shot" (18 slides total).
- video guide: Part 1 (run-all) + Part 2 (run-hardening) with pre-flight note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 23:51:11 +09:00

426 lines
28 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CASAN Harness — FPT · AI-SDLC có kiểm soát</title>
<style>
:root{
--fpt-orange:#F37021; --fpt-blue:#00AEEF; --fpt-green:#7DBB42;
--bg:#070B16; --ink:#eaf0ff; --muted:#93a0c2;
--glass:rgba(255,255,255,.045); --glass-brd:rgba(255,255,255,.10);
--h4:#ff5a5a; --h5:#3ba7ff; --h6:#5fd08a; --h7:#b98bff;
--bad:#ff6b6b; --ok:#5fd08a;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
font-family:"Segoe UI",system-ui,-apple-system,"Noto Sans",sans-serif;
color:var(--ink); overflow:hidden; background:var(--bg); position:relative;
}
/* AI-era ambient background */
body::before{content:"";position:fixed;inset:0;z-index:0;
background:
radial-gradient(900px 520px at 8% -8%, rgba(243,112,33,.20), transparent 60%),
radial-gradient(900px 520px at 100% 0%, rgba(0,174,239,.18), transparent 55%),
radial-gradient(700px 500px at 60% 120%, rgba(125,187,66,.12), transparent 60%);}
body::after{content:"";position:fixed;inset:0;z-index:0;opacity:.35;
background-image:radial-gradient(rgba(255,255,255,.05) 1px,transparent 1px);
background-size:26px 26px;}
.deck{position:fixed;inset:0;z-index:1}
.slide{position:absolute;inset:0;display:none;flex-direction:column;
justify-content:center;padding:6vh 7vw;animation:fade .4s ease}
.slide.active{display:flex}
@keyframes fade{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.eyebrow{font-family:"Cascadia Code",Consolas,monospace;color:var(--fpt-orange);
font-weight:700;letter-spacing:3px;text-transform:uppercase;
font-size:clamp(11px,1.2vw,15px);margin-bottom:1em;display:flex;align-items:center;gap:.6em}
.eyebrow::before{content:"";width:26px;height:2px;background:var(--fpt-orange)}
h1{font-size:clamp(30px,5.2vw,64px);line-height:1.06;letter-spacing:-1px;font-weight:800}
h2{font-size:clamp(23px,3.6vw,44px);line-height:1.12;font-weight:800;margin-bottom:.4em}
.grad{background:linear-gradient(100deg,var(--fpt-orange),#ffb46b 40%,var(--fpt-blue));
-webkit-background-clip:text;background-clip:text;color:transparent}
.sub{color:var(--muted);font-size:clamp(15px,1.9vw,23px);margin-top:.8em;line-height:1.55}
ul{margin-top:1.1em;list-style:none;display:grid;gap:.7em}
li{font-size:clamp(15px,1.95vw,24px);line-height:1.42;padding-left:1.7em;position:relative}
li::before{content:"›";position:absolute;left:0;color:var(--fpt-orange);font-weight:800}
b,strong{color:#fff}
code{font-family:"Cascadia Code",Consolas,monospace;background:rgba(255,255,255,.06);
padding:.05em .4em;border-radius:6px;font-size:.9em;color:#ffd8b8}
.tag{display:inline-block;font-family:monospace;font-size:.6em;font-weight:800;padding:.2em .7em;
border-radius:999px;vertical-align:middle;letter-spacing:.5px}
.tag.real{background:rgba(125,187,66,.18);color:#b6f08a;border:1px solid #7dbb4266}
.tag.warn{background:rgba(243,112,33,.16);color:#ffc07a;border:1px solid #f3702166}
/* glass card */
.cards{display:grid;gap:1rem;margin-top:1.3em}
.c4{grid-template-columns:repeat(4,1fr)} .c3{grid-template-columns:repeat(3,1fr)}
.c2{grid-template-columns:repeat(2,1fr)}
.card{background:var(--glass);border:1px solid var(--glass-brd);border-radius:18px;
padding:1.1em 1.15em;backdrop-filter:blur(10px);box-shadow:0 10px 40px rgba(0,0,0,.3)}
.card h3{font-size:clamp(14px,1.7vw,21px);margin-bottom:.4em;display:flex;align-items:center;gap:.4em}
.card p{color:var(--muted);font-size:clamp(12px,1.35vw,16px);line-height:1.42}
.card.on4{border-top:3px solid var(--h4)} .card.on5{border-top:3px solid var(--h5)}
.card.on6{border-top:3px solid var(--h6)} .card.on7{border-top:3px solid var(--h7)}
/* before/after */
.ba{display:grid;grid-template-columns:1fr auto 1fr;gap:1.1rem;align-items:stretch;margin-top:1.2em}
.col{border-radius:18px;padding:1.15em 1.25em;backdrop-filter:blur(8px)}
.before{background:rgba(255,90,90,.07);border:1px solid rgba(255,90,90,.28)}
.after{background:rgba(125,187,66,.08);border:1px solid rgba(125,187,66,.32)}
.col .lbl{font-family:monospace;font-weight:800;letter-spacing:1px;font-size:.8em;margin-bottom:.6em}
.before .lbl{color:var(--bad)} .after .lbl{color:var(--ok)}
.col ul{margin-top:.2em;gap:.5em} .col li{font-size:clamp(13px,1.55vw,20px);padding-left:1.4em}
.before li::before{content:"✕";color:var(--bad)} .after li::before{content:"✓";color:var(--ok)}
.mid{display:flex;align-items:center;font-size:clamp(22px,3vw,40px);color:var(--fpt-orange)}
table{width:100%;border-collapse:collapse;margin-top:1.2em;font-size:clamp(13px,1.65vw,21px)}
th,td{text-align:left;padding:.52em .7em;border-bottom:1px solid var(--glass-brd)}
th{color:var(--fpt-blue);font-family:monospace;font-size:.82em;text-transform:uppercase;letter-spacing:1px}
td.big{font-weight:800;color:#fff} td.was{color:var(--muted)}
.flow{display:flex;align-items:center;gap:.6rem;margin-top:1.4em;flex-wrap:wrap}
.node{background:var(--glass);border:1px solid var(--glass-brd);border-radius:14px;
padding:.75em 1.05em;font-weight:700;font-size:clamp(13px,1.55vw,20px);text-align:center;backdrop-filter:blur(8px)}
.node.in{border-color:rgba(0,174,239,.5)} .node.out{border-color:rgba(125,187,66,.5);background:rgba(125,187,66,.08)}
.arrow{color:var(--fpt-orange);font-size:clamp(18px,2.3vw,30px)}
.chips{display:flex;gap:.5rem;margin-top:1.1em;flex-wrap:wrap}
.chip{padding:.5em .9em;border-radius:11px;font-weight:700;font-size:clamp(11px,1.3vw,17px);
border:1px solid var(--glass-brd);background:var(--glass)}
.chip.s{border-color:var(--h4);color:#ffb4b4} .chip.g{border-color:var(--h5);color:#a9d5ff}
.chip.o{border-color:var(--h6);color:#a6f0c0} .chip.r{border-color:var(--h7);color:#dcc0ff}
.chip.y{border-color:var(--fpt-orange);color:#ffc99b}
.term{margin-top:1.2em;background:rgba(3,5,12,.7);border:1px solid var(--glass-brd);border-radius:14px;
padding:1em 1.25em;font-family:"Cascadia Code",Consolas,monospace;
font-size:clamp(12px,1.45vw,19px);line-height:1.75;backdrop-filter:blur(8px)}
.term .dim{color:#5a678c} .term .ok{color:#8ff0b0;font-weight:700} .term .no{color:#ff9a9a;font-weight:700}
.quote{font-size:clamp(21px,3.3vw,44px);line-height:1.22;font-weight:800}
.quote .hl{color:transparent;background:linear-gradient(100deg,var(--fpt-orange),var(--fpt-blue));
-webkit-background-clip:text;background-clip:text}
/* score meters */
.meters{display:grid;grid-template-columns:1fr 1fr;gap:.7em 1.6em;margin-top:1.2em;max-width:1050px}
.meter{display:grid;grid-template-columns:180px 1fr 44px;align-items:center;gap:.8em}
.meter .m-l{font-size:clamp(12px,1.4vw,18px);color:var(--muted)}
.track{height:10px;border-radius:999px;background:rgba(255,255,255,.07);overflow:hidden}
.fill{height:100%;border-radius:999px;background:linear-gradient(90deg,var(--fpt-orange),var(--fpt-blue))}
.meter .m-v{font-weight:800;text-align:right;font-family:monospace}
/* chrome */
.bar{position:fixed;top:0;left:0;height:4px;z-index:9;transition:width .35s;
background:linear-gradient(90deg,var(--fpt-orange),var(--fpt-blue),var(--fpt-green))}
.brand{position:fixed;top:20px;right:26px;z-index:9;display:flex;align-items:center;gap:10px}
.brand .fpt{font-weight:900;font-size:20px;letter-spacing:1px;
background:linear-gradient(100deg,var(--fpt-orange),var(--fpt-blue),var(--fpt-green));
-webkit-background-clip:text;background-clip:text;color:transparent}
.brand .ai{font-family:monospace;font-size:11px;color:var(--muted);border:1px solid var(--glass-brd);
padding:2px 8px;border-radius:999px}
.foot{position:fixed;bottom:16px;left:0;right:0;display:flex;justify-content:space-between;
align-items:center;padding:0 26px;color:var(--muted);font-size:13px;z-index:9;font-family:monospace}
.dots{display:flex;gap:6px} .dot{width:8px;height:8px;border-radius:50%;background:#2a3358;cursor:pointer;transition:.2s}
.dot.on{background:var(--fpt-orange);transform:scale(1.3)}
.hint{position:fixed;bottom:14px;left:50%;transform:translateX(-50%);color:#48557d;font-size:11px;z-index:9;font-family:monospace}
.kbd{border:1px solid var(--glass-brd);border-radius:6px;padding:1px 7px}
</style>
</head>
<body>
<div class="bar" id="bar"></div>
<div class="brand"><span class="fpt">FPT</span><span class="ai">AI-SDLC · CASAN</span></div>
<div class="deck" id="deck">
<!-- 1 TITLE -->
<section class="slide active">
<div class="eyebrow">FPT · CASAN Harness · Thời đại AI</div>
<h1>Cải thiện <span class="grad">H4 · H5 · H6</span><br/>cho AI-SDLC <span class="grad">có kiểm soát</span></h1>
<p class="sub">Chúng tôi không hỏi "AI viết code nhanh cỡ nào" — mà hỏi:
<b>khi AI làm bậy, ai chặn? và làm sao chứng minh đã chặn?</b></p>
<p class="sub">Chạy có bằng chứng · Chặn thật · Trung thực về giới hạn · Hướng đóng gói production.</p>
</section>
<!-- 2 GOAL / 3 AXES -->
<section class="slide">
<div class="eyebrow">Mục tiêu trình bày</div>
<h2>Ba trục chúng tôi chứng minh</h2>
<div class="cards c3">
<div class="card on4"><h3>🔴 1 · Cải thiện H4·H5·H6</h3><p>Before → After cho từng harness, kèm <b>bằng chứng đo thật</b> (exit-code, số test).</p></div>
<div class="card on5"><h3>🧠 2 · Hiểu hệ thống sâu</h3><p>Truy đến <b>gốc lỗi</b> (fail-open), threat-model đường lọt, nguyên tắc "harness thấp nhất quyết định trần".</p></div>
<div class="card on6"><h3>📦 3 · Hướng production</h3><p>Thang điểm sẵn sàng, <b>đóng gói package</b> tái dùng, lộ trình hardening có test.</p></div>
</div>
<p class="sub">Mọi con số gắn nhãn <span class="tag real">ĐO THẬT</span> — giám khảo chạy lại ra đúng.</p>
</section>
<!-- 3 DEPTH: root cause -->
<section class="slide">
<div class="eyebrow">Hiểu sâu · Truy gốc lỗi</div>
<h2>Điểm mù chí mạng: <span style="color:var(--h4)">fail-open</span></h2>
<ul>
<li>Bản trước dùng <code>grep "[:space:]"</code> — cú pháp <b>sai</b> trên grep hiện đại → thoát <b style="color:var(--bad)">rc=4</b>.</li>
<li>Hệ quả: bộ lọc "tưởng đang chặn" nhưng thực chất <b style="color:var(--bad)">chặn = 0</b> — lọt cả injection kinh điển.</li>
<li>Bài học: <b>"có prompt-filter.yaml" ≠ "chặn được thật"</b>. Chỉ tính điểm khi chặn được tấn công thật.</li>
</ul>
<p class="sub">Phát hiện được lỗi fail-open này = hiểu hệ thống ở tầng thực thi, không dừng ở tài liệu.</p>
</section>
<!-- 4 OVERVIEW -->
<section class="slide">
<div class="eyebrow">Kiến trúc CASAN</div>
<h2>Mọi lời gọi agent đi xuyên <span class="grad">7 harness</span></h2>
<div class="flow">
<div class="node in">📥 INPUT</div><div class="arrow">→</div>
<div class="node">🧠 Boss · 13 bước AI-SDLC</div><div class="arrow">→</div>
<div class="node out">📤 code + BẰNG CHỨNG</div>
</div>
<div class="chips">
<span class="chip y">H1 Context</span><span class="chip y">H2 Tool</span><span class="chip y">H3 Eval</span>
<span class="chip s">H4 Security</span><span class="chip g">H5 Governance</span>
<span class="chip o">H6 AgentOps</span><span class="chip r">H7 Orchestration</span>
</div>
<p class="sub">Gate trả <b>APPROVE / REJECT / BLOCK</b> — kiểm soát bọc mọi bước, không đứng bên lề.</p>
</section>
<!-- 5 H4 -->
<section class="slide">
<div class="eyebrow">Trục 1 · 🔴 H4 Security</div>
<h2>Từ fail-open → <span class="grad">chặn thật đa lớp</span></h2>
<div class="ba">
<div class="col before"><div class="lbl">BEFORE</div><ul>
<li>grep sai → fail-open rc=4, chặn = 0</li>
<li>chỉ regex tiếng Anh</li>
<li>mù với câu diễn đạt mới</li></ul></div>
<div class="mid">→</div>
<div class="col after"><div class="lbl">AFTER</div><ul>
<li>BLOCK <b>rc=2</b> + normalize leetspeak</li>
<li>+ <b>semantic model-as-judge</b> + <b>strict fail-closed</b></li>
<li><b>homoglyph · zero-width · base64</b> đều chặn</li>
<li>artifact-scan + <b>tool-output scan</b> · secret/PII block</li></ul></div>
</div>
<p class="sub"><span class="tag real">ĐO THẬT</span> Adversarial <b>44/44</b> + Track A <b>25/25</b> · homoglyph/base64 → <code>rc=2</code> · strict fail-closed → <code>rc=2</code>.</p>
</section>
<!-- 6 H5 -->
<section class="slide">
<div class="eyebrow">Trục 1 · 🔵 H5 Governance</div>
<h2>Từ log sửa được → <span class="grad">audit bất biến, ký số</span></h2>
<div class="ba">
<div class="col before"><div class="lbl">BEFORE</div><ul>
<li>log thường, sửa được</li>
<li>không chống giả mạo</li>
<li>không truy vết ký số</li></ul></div>
<div class="mid">→</div>
<div class="col after"><div class="lbl">AFTER</div><ul>
<li><b>hash-chain + ký RSA</b> HEAD</li>
<li>sửa 1 ký tự → <b>AUDIT_HASH_MISMATCH</b></li>
<li><b>telemetry token/cost</b> cũng được ký (bất biến)</li>
<li>secrets-scan · quét no-bypass</li></ul></div>
</div>
<p class="sub"><span class="tag real">ĐO THẬT</span> tamper audit → <code>AUDIT_HASH_MISMATCH</code> · sửa 1 token telemetry → <code>TELEMETRY_INTEGRITY_MISMATCH</code>.</p>
</section>
<!-- 7 H6 -->
<section class="slide">
<div class="eyebrow">Trục 1 · 🟢 H6 AgentOps</div>
<h2>Từ mù chi phí → <span class="grad">giám sát & chặn spike</span></h2>
<div class="ba">
<div class="col before"><div class="lbl">BEFORE</div><ul>
<li>không đo chi phí</li>
<li>không telemetry token</li>
<li>không phát hiện bất thường</li></ul></div>
<div class="mid">→</div>
<div class="col after"><div class="lbl">AFTER</div><ul>
<li><b>cost-spike 3× → exit=2</b></li>
<li>+ <b>trần tuyệt đối/call</b> + <b>ngân sách tích luỹ</b></li>
<li>bắt cả <b>slow-boil</b> + <b>spray</b> + cold-start</li>
<li>telemetry token thật · drift · circuit-breaker</li></ul></div>
</div>
<p class="sub"><span class="tag real">ĐO THẬT</span> spike/slow-boil/spray → <code>exit=2</code> · bình thường → <code>exit=0</code> — không né được bằng median.</p>
</section>
<!-- 8 EVIDENCE -->
<section class="slide">
<div class="eyebrow">Bằng chứng tổng hợp <span class="tag real">ĐO THẬT</span></div>
<h2>Kiểm chứng ngay trên máy — <span class="grad">140 checks, 0 fail</span></h2>
<div class="term">
<div><span class="dim">$</span> run-casan4-harness-tests.sh → <span class="ok">35/35 PASS</span></div>
<div><span class="dim">$</span> adversarial-harness-tests.sh → <span class="ok">44/44 PASS</span></div>
<div><span class="dim">$</span> phase1-track-a-tests.sh → <span class="ok">25/25 PASS</span> <span class="dim">(hardening)</span></div>
<div><span class="dim">$</span> phase2-track-c-tests.sh → <span class="ok">29/29 PASS</span> <span class="dim">(C-MVP)</span></div>
<div><span class="dim">$</span> phase3-evidence-pack-tests.sh → <span class="ok">7/7 PASS</span></div>
<div><span class="dim">$</span> homoglyph/base64 inject → <span class="no">BLOCKED rc=2</span> · tamper token → <span class="no">TELEMETRY_MISMATCH</span></div>
</div>
<p class="sub">Baseline <b>79</b> giữ nguyên · <b>+61</b> hardening = <b>140</b>. 👉 Chiếu terminal thật khi trình bày.</p>
</section>
<!-- 8b TRACK A DELIVERED -->
<section class="slide">
<div class="eyebrow">Trục 3 · Track A <span class="tag real">ĐÃ LÀM + TEST</span></div>
<h2>Hardening H4·H5·H6 — <span class="grad">đánh bại thứ regex cũ bỏ sót</span></h2>
<div class="cards c3">
<div class="card on4"><h3>🔴 H4+</h3><p><b>Homoglyph · zero-width · fullwidth · base64</b> đều chặn (rc=2). <b>Strict fail-closed</b>: model chết → BLOCK, không SKIP âm thầm. Quét cả tool-output.</p></div>
<div class="card on5"><h3>🔵 H5+</h3><p><b>Telemetry token/cost</b> vào manifest ký số — sửa 1 byte → <code>MISMATCH</code>. Bất biến như audit chain.</p></div>
<div class="card on6"><h3>🟢 H6+</h3><p><b>Trần tuyệt đối/call</b> + <b>ngân sách tích luỹ</b> — bắt slow-boil & spray & cold-start, ngoài spike 3×median.</p></div>
</div>
<p class="sub"><span class="tag real">ĐO THẬT</span> Benign corpus <b>95 mẫu EN/VI/JA</b> → <b>FP = 0%</b> · adversarial block <b>100%</b> · CRITICAL <b>100%</b> — siết chặt mà <b>không bắt nhầm</b>.</p>
</section>
<!-- 8c EVIDENCE PACK money-shot -->
<section class="slide">
<div class="eyebrow">Plan-09 · Evidence Pack <span class="tag real">MVP ĐÃ LÀM</span></div>
<h2>"Vì sao tin output này?" → <span class="grad">gói bằng chứng ký số</span></h2>
<div class="term">
<div><span class="dim">$</span> casan pack &lt;run&gt; → <span class="ok">EVIDENCE_PACK_CREATED</span> <span class="dim">(12 file: h1..h7 + redteam + cost + manifest + decision-log)</span></div>
<div><span class="dim">$</span> casan verify-pack &lt;run&gt; → <span class="ok">EVIDENCE_PACK_VALID anchor=signed</span></div>
<div><span class="dim">$</span> <span class="dim"># sửa 1 byte trong pack…</span></div>
<div><span class="dim">$</span> casan verify-pack &lt;run&gt; → <span class="no">EVIDENCE_PACK_TAMPERED · exit=1</span></div>
<div><span class="dim">$</span> certified = <b>chỉ true khi ĐỦ cổng</b> (audit✓ telemetry✓ cost✓ FP✓), thiếu → ghi lý do, KHÔNG chứng nhận khống</div>
</div>
<p class="sub">Đổi <b>1 byte</b> → chứng nhận <b>vô hiệu</b>. Manifest hash + chữ ký RSA trên head → tamper-evident thật.</p>
</section>
<!-- 9 DEPTH: threat model + principle -->
<section class="slide">
<div class="eyebrow">Trục 2 · Hiểu sâu · nhận diện → VÁ</div>
<h2>Nhận diện đường lọt — và <span class="grad">Track A đã đóng</span></h2>
<div class="cards c3">
<div class="card on4"><h3>🔴 H4</h3><p><span class="tag real">ĐÃ VÁ</span> Semantic SKIP → strict fail-closed · homoglyph/encoding → chặn. <span class="tag warn">CÒN</span> đa ngôn ngữ, inject-classifier (Track B).</p></div>
<div class="card on5"><h3>🔵 H5</h3><p><span class="tag real">ĐÃ VÁ</span> Telemetry vào chuỗi ký. <span class="tag warn">CÒN</span> quản lý khóa HSM, TOCTOU (Track B).</p></div>
<div class="card on6"><h3>🟢 H6</h3><p><span class="tag real">ĐÃ VÁ</span> Slow-boil + dưới-ngưỡng + cold-start → trần tuyệt đối/tích luỹ. <span class="tag warn">CÒN</span> circuit theo tỷ lệ (Track B).</p></div>
</div>
<p class="sub">Chuẩn: OWASP LLM/Agentic · CSA MAESTRO · MITRE ATLAS. Nguyên tắc: <b>"harness thấp nhất quyết định trần"</b>. Mỗi vá kèm test đối kháng fail-able.</p>
</section>
<!-- 10 MODEL -->
<section class="slide">
<div class="eyebrow">Triết lý model · local-first</div>
<h2 class="quote">"Model sinh <span class="hl">bản nháp</span>; harness quyết định bản nháp có được <span class="hl">tin</span> hay không."</h2>
<ul>
<li>Local (Ollama) đủ cho harness — <b>không API key, offline, dữ liệu không rời máy</b> (Sovereign AI).</li>
<li>Đổi model <b>không đổi</b> mức an toàn — harness giữ đảm bảo, bất kể model.</li>
<li>H6 cost-spike chặn đốt token → điểm cộng là <b>kiểm soát chi phí</b>, không phải "model xịn nhất".</li>
</ul>
</section>
<!-- 11 PRODUCTION READINESS -->
<section class="slide">
<div class="eyebrow">Trục 3 · Hướng production · sau Track A + C-MVP</div>
<h2>Thang sẵn sàng: <span class="grad">~3.8–4.0/5</span> (production nội bộ)</h2>
<div class="meters">
<div class="meter"><div class="m-l">Phủ phát hiện</div><div class="track"><div class="fill" style="width:80%"></div></div><div class="m-v">4</div></div>
<div class="meter"><div class="m-l">Fail-safe</div><div class="track"><div class="fill" style="width:90%"></div></div><div class="m-v">4.5</div></div>
<div class="meter"><div class="m-l">Chống giả mạo</div><div class="track"><div class="fill" style="width:80%"></div></div><div class="m-v">4</div></div>
<div class="meter"><div class="m-l">Kiểm soát chi phí</div><div class="track"><div class="fill" style="width:80%"></div></div><div class="m-v">4</div></div>
<div class="meter"><div class="m-l">Tool-authz / supply-chain</div><div class="track"><div class="fill" style="width:70%"></div></div><div class="m-v">3.5</div></div>
<div class="meter"><div class="m-l">Đa domain / i18n</div><div class="track"><div class="fill" style="width:40%"></div></div><div class="m-v">2</div></div>
</div>
<p class="sub"><span class="tag warn">TRUNG THỰC</span> Track A + C-MVP + Evidence Pack <b>đã làm</b> → ~3.8–4.0. <b>Track B + C-Governance/Ops + sandbox cô lập thật</b> → production nghiêm túc (roadmap sau thi).</p>
</section>
<!-- 11b TRACK C-1 -->
<section class="slide">
<div class="eyebrow">Trục 3 · Track C-MVP <span class="tag real">ĐÃ LÀM + TEST (29/29)</span></div>
<h2>Kiểm soát <span class="grad">ngoài</span> H4·H5·H6 — đã dựng minimum bar</h2>
<p class="sub">Trả đòn phản biện "agent vẫn có thể <b>thêm dependency độc</b> / <b>ghi .env</b>?" — nay đã có gate thật, chạy được, có test.</p>
<div class="cards c4">
<div class="card on4"><h3>🔐 Tool authorization</h3><p>Gate cả <b>hành động</b>: <code>.env</code>/private-key/CI-config → BLOCK · <code>rm -rf</code>/<code>curl|bash</code> → BLOCK · egress → duyệt.</p></div>
<div class="card on6"><h3>📦 Supply-chain</h3><p><b>typosquat + postinstall + gói độc → BLOCK</b> · dep mới → duyệt · dep-diff report.</p></div>
<div class="card on4"><h3>🕵️ Data exfiltration</h3><p>secret→cloud/artifact <b>BLOCK</b> · PII→audit <b>MASK</b>.</p></div>
<div class="card on7"><h3>🧪 Runtime sandbox <span class="tag warn">scaffold</span></h3><p>Chặn đọc ~/.ssh · net egress · fork-bomb · ghi ngoài workspace + ulimit. <b>Chưa</b> cô lập kernel.</p></div>
</div>
<p class="sub">Outcome chuẩn hoá thật: <code>ALLOW · WARN · REQUIRE_APPROVAL · BLOCK</code>. Approval cần <b>người duyệt định danh</b> (audit).</p>
</section>
<!-- 11c TRACK C-2 -->
<section class="slide">
<div class="eyebrow">Trục 3 · Track C · Governance & Ops</div>
<h2>Quản trị & vận hành <span class="grad">mức enterprise</span></h2>
<div class="cards c4">
<div class="card on5"><h3>📝 Policy approval <span class="tag warn">roadmap</span></h3><p>Versioning + reviewer bắt buộc · audit actor · rollback policy.</p></div>
<div class="card on5"><h3>🗄️ External audit <span class="tag warn">roadmap</span></h3><p>Append-only (WORM) ngoài runtime · alert khi chain đứt.</p></div>
<div class="card on6"><h3>🚨 Incident response <span class="tag warn">roadmap</span></h3><p>Severity CRIT→MED · owner · kill-switch theo project/model.</p></div>
<div class="card"><h3>✓ Benign / FP <span class="tag real">ĐÃ LÀM</span></h3><p>95 mẫu EN/VI/JA · <b>FP = 0%</b> · block 100% · CRITICAL 100%.</p></div>
</div>
<p class="sub"><span class="tag warn">CÒN LẠI (sau thi)</span> Policy-approval · WORM audit · incident kill-switch — enterprise governance/ops, đã có lộ trình task-level.</p>
</section>
<!-- 12 PACKAGING -->
<section class="slide">
<div class="eyebrow">Trục 3 · Đóng gói & tái sử dụng</div>
<h2>Giá trị ở <span class="grad">harness tái dùng</span>, không ở app OKR</h2>
<ul>
<li>Đóng gói <b>package có version</b> — <code>fpt-casan-sdd-harness</code>.</li>
<li>Registry + <code>verify-harness-reuse</code> → nhiều dự án dùng chung.</li>
<li>Áp dự án mới = cắm golden/corpus/input + đăng ký, <b>không sửa gate</b>.</li>
<li>App OKR chỉ là <b>testbed cố định</b> để so sánh công bằng.</li>
</ul>
</section>
<!-- 13 ROADMAP -->
<section class="slide">
<div class="eyebrow">Lộ trình · kế hoạch task-level</div>
<h2>Tư duy sản phẩm, không chỉ demo</h2>
<div class="cards c4">
<div class="card"><h3>01</h3><p>Tái cấu trúc thư mục</p></div>
<div class="card"><h3>02</h3><p>Nối LLM sinh source</p></div>
<div class="card"><h3>03</h3><p>Patch cloud (bỏ stub)</p></div>
<div class="card"><h3>04</h3><p>Khép vòng tự cải tiến</p></div>
<div class="card"><h3>05</h3><p>CI/CD + phát hành</p></div>
<div class="card"><h3>06</h3><p>Onboard dự án 2</p></div>
<div class="card on4"><h3>07 ✅</h3><p>Hardening Track A + C-MVP <b>(đã làm)</b></p></div>
<div class="card on6"><h3>09 ✅</h3><p>Evidence Pack MVP <b>(đã làm)</b></p></div>
</div>
<p class="sub"><span class="tag real">ĐÃ LÀM</span> 07 Track A + C-MVP · 09 Evidence Pack — có test (140 checks). <span class="tag warn">SAU THI</span> 07 Track B + C-Gov/Ops · 08 · 10 · 12.</p>
</section>
<!-- 14 CLOSE -->
<section class="slide">
<div class="eyebrow">Chốt</div>
<h1 class="quote">Không phải AI <span class="hl">xịn nhất</span> —<br/>mà AI <span class="hl">có kiểm soát, có bằng chứng, tái dùng được</span>.</h1>
<ul>
<li>H4·H5·H6 cải thiện có <b>before/after + exit-code đo thật</b>.</li>
<li>Hiểu hệ thống tới gốc lỗi + threat-model đường lọt.</li>
<li>Hướng production: đóng gói package + lộ trình hardening có test.</li>
</ul>
</section>
</div>
<div class="foot">
<div id="who">FPT · CASAN Harness</div>
<div class="dots" id="dots"></div>
<div id="num">1 / 16</div>
</div>
<div class="hint"><span class="kbd">←</span> <span class="kbd">→</span> / <span class="kbd">Space</span> chuyển slide · <span class="kbd">F</span> toàn màn hình</div>
<script>
const slides=[...document.querySelectorAll('.slide')];
const dotsBox=document.getElementById('dots');
const bar=document.getElementById('bar'),num=document.getElementById('num');
let i=0;
slides.forEach((_,k)=>{const d=document.createElement('div');d.className='dot'+(k===0?' on':'');
d.onclick=()=>go(k);dotsBox.appendChild(d);});
const dots=[...document.querySelectorAll('.dot')];
function go(n){
i=Math.max(0,Math.min(slides.length-1,n));
slides.forEach((s,k)=>s.classList.toggle('active',k===i));
dots.forEach((d,k)=>d.classList.toggle('on',k===i));
bar.style.width=((i+1)/slides.length*100)+'%';
num.textContent=(i+1)+' / '+slides.length;
}
document.addEventListener('keydown',e=>{
if(['ArrowRight','ArrowDown',' ','PageDown'].includes(e.key)){e.preventDefault();go(i+1);}
else if(['ArrowLeft','ArrowUp','PageUp'].includes(e.key)){e.preventDefault();go(i-1);}
else if(e.key==='Home')go(0); else if(e.key==='End')go(slides.length-1);
else if(e.key.toLowerCase()==='f'){if(!document.fullscreenElement)document.documentElement.requestFullscreen();else document.exitFullscreen();}
});
let sx=0;
document.addEventListener('touchstart',e=>sx=e.touches[0].clientX,{passive:true});
document.addEventListener('touchend',e=>{const dx=e.changedTouches[0].clientX-sx;
if(Math.abs(dx)>50)go(i+(dx<0?1:-1));},{passive:true});
go(0);
</script>
</body>
</html>