070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
409 lines
27 KiB
HTML
409 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Turn an Incident Retro into a Learning Deck like a Platform VP - Product management</title>
|
||
<style>/* html-ppt :: shared webfonts (trimmed to faces actually in use) */
|
||
@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800;900&display=swap');
|
||
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap');
|
||
</style>
|
||
<style>/* html-ppt :: base.css — reset + shared tokens + layout primitives */
|
||
/* Default tokens. Themes in assets/themes/*.css override the :root block. */
|
||
:root {
|
||
--bg: #ffffff;
|
||
--bg-soft: #f7f7f8;
|
||
--surface: #ffffff;
|
||
--surface-2: #f2f2f4;
|
||
--border: rgba(0,0,0,.08);
|
||
--border-strong: rgba(0,0,0,.16);
|
||
--text-1: #111216;
|
||
--text-2: #55596a;
|
||
--text-3: #8a8f9e;
|
||
--accent: #B5392A;
|
||
--good: #1aaf6c;
|
||
--warn: #f5a524;
|
||
--bad: #e0445a;
|
||
--radius: 2px;
|
||
--radius-sm: 2px;
|
||
--radius-lg: 3px;
|
||
--shadow: none;
|
||
--shadow-lg: none;
|
||
--font-sans: 'Archivo',-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
|
||
--font-serif: 'Archivo',Georgia,serif;
|
||
--font-mono: 'IBM Plex Mono',SFMono-Regular,Menlo,monospace;
|
||
--font-display: var(--font-sans);
|
||
--letter-tight: -.03em;
|
||
--letter-normal: -.01em;
|
||
--ease: cubic-bezier(.16,1,.3,1);
|
||
}
|
||
|
||
*,*::before,*::after{box-sizing:border-box}
|
||
html,body{margin:0;padding:0;background:var(--bg);color:var(--text-1);
|
||
font-family:var(--font-sans);font-weight:400;line-height:1.6;
|
||
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
|
||
letter-spacing:var(--letter-normal)}
|
||
img,svg,video{max-width:100%;display:block}
|
||
a{color:var(--accent);text-decoration:none}
|
||
a:hover{text-decoration:underline}
|
||
code,kbd,pre,samp{font-family:var(--font-mono)}
|
||
|
||
/* ================= SLIDE SYSTEM ================= */
|
||
.deck{position:relative;width:100vw;height:100vh;overflow:hidden;background:var(--bg)}
|
||
.slide{
|
||
position:absolute;inset:0;
|
||
display:flex;flex-direction:column;justify-content:center;
|
||
padding:72px 96px;
|
||
box-sizing:border-box;
|
||
opacity:0;pointer-events:none;
|
||
transition:opacity .5s var(--ease), transform .5s var(--ease);
|
||
transform:translateX(30px);
|
||
overflow:hidden;
|
||
}
|
||
.slide.is-active{opacity:1;pointer-events:auto;transform:translateX(0);z-index:2}
|
||
.slide.is-prev{transform:translateX(-30px)}
|
||
|
||
/* single-page standalone (used when a layout file is opened directly) */
|
||
body.single .slide{position:relative;width:100vw;height:100vh;opacity:1;transform:none;pointer-events:auto}
|
||
|
||
/* ================= TYPOGRAPHY ================= */
|
||
.eyebrow{font-size:13px;font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:var(--text-3)}
|
||
.kicker{font-size:14px;font-weight:600;color:var(--accent);letter-spacing:.08em;text-transform:uppercase}
|
||
h1.title,.h1{font-family:var(--font-display);font-size:72px;line-height:1.05;font-weight:800;letter-spacing:var(--letter-tight);margin:0 0 18px;color:var(--text-1)}
|
||
h2.title,.h2{font-family:var(--font-display);font-size:54px;line-height:1.1;font-weight:700;letter-spacing:var(--letter-tight);margin:0 0 14px}
|
||
h3,.h3{font-size:32px;line-height:1.2;font-weight:600;letter-spacing:var(--letter-normal);margin:0 0 10px}
|
||
h4,.h4{font-size:22px;line-height:1.3;font-weight:600;margin:0 0 8px}
|
||
.lede{font-size:22px;line-height:1.55;color:var(--text-2);font-weight:300;max-width:62ch}
|
||
.dim{color:var(--text-2)}
|
||
.dim2{color:var(--text-3)}
|
||
.mono{font-family:var(--font-mono)}
|
||
.serif{font-family:var(--font-serif)}
|
||
.gradient-text{color:var(--accent)} /* gradient text retired: single-accent discipline */
|
||
|
||
/* ================= LAYOUT PRIMITIVES ================= */
|
||
.stack>*+*{margin-top:14px}
|
||
.row{display:flex;gap:24px;align-items:center}
|
||
.row.wrap{flex-wrap:wrap}
|
||
.grid{display:grid;gap:24px}
|
||
.g2{grid-template-columns:repeat(2,1fr)}
|
||
.g3{grid-template-columns:repeat(3,1fr)}
|
||
.g4{grid-template-columns:repeat(4,1fr)}
|
||
.center{display:flex;align-items:center;justify-content:center;text-align:center}
|
||
.fill{flex:1}
|
||
.sp-t{padding-top:24px}.sp-b{padding-bottom:24px}
|
||
.mt-s{margin-top:8px}.mt-m{margin-top:18px}.mt-l{margin-top:32px}
|
||
.mb-s{margin-bottom:8px}.mb-m{margin-bottom:18px}.mb-l{margin-bottom:32px}
|
||
|
||
/* ================= CARDS ================= */
|
||
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
|
||
padding:26px 28px;box-shadow:var(--shadow);position:relative;overflow:hidden}
|
||
.card-soft{background:var(--surface-2);border:1px solid var(--border)}
|
||
.card-outline{background:transparent;border:1.5px solid var(--border-strong);box-shadow:none}
|
||
.card-accent{background:var(--surface);border-top:3px solid var(--accent)}
|
||
.card-hover{transition:transform .3s var(--ease),box-shadow .3s var(--ease)}
|
||
.card-hover:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}
|
||
|
||
.pill{display:inline-block;padding:4px 12px;border-radius:999px;font-size:12px;font-weight:500;
|
||
background:var(--surface-2);color:var(--text-2);border:1px solid var(--border)}
|
||
.pill-accent{background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent);border-color:color-mix(in srgb,var(--accent) 28%,transparent)}
|
||
|
||
/* ================= BARS / DIVIDERS ================= */
|
||
.divider{height:1px;background:var(--border);width:100%}
|
||
.divider-accent{height:3px;width:72px;background:var(--accent);border-radius:2px}
|
||
|
||
/* ================= CHROME (header/footer/progress) ================= */
|
||
.deck-header{position:absolute;top:24px;left:40px;right:40px;display:flex;align-items:center;justify-content:space-between;
|
||
font-size:12px;color:var(--text-3);letter-spacing:.12em;text-transform:uppercase;z-index:10;pointer-events:none}
|
||
.deck-footer{position:absolute;bottom:24px;left:40px;right:40px;display:flex;align-items:center;justify-content:space-between;
|
||
font-size:12px;color:var(--text-3);z-index:10;pointer-events:none}
|
||
.slide-number::before{content:attr(data-current)}
|
||
.slide-number::after{content:" / " attr(data-total)}
|
||
.progress-bar{position:fixed;left:0;right:0;bottom:0;height:3px;background:transparent;z-index:20}
|
||
.progress-bar > span{display:block;height:100%;width:0;background:var(--accent);transition:width .3s var(--ease)}
|
||
|
||
/* ================= PRESENTER / OVERVIEW ================= */
|
||
.notes{display:none!important}
|
||
.notes-overlay{position:fixed;inset:auto 0 0 0;max-height:42vh;background:rgba(20,22,30,.95);color:#e8ebf4;
|
||
padding:20px 32px;font-size:16px;line-height:1.6;border-top:1px solid rgba(255,255,255,.1);transform:translateY(100%);
|
||
transition:transform .3s var(--ease);z-index:40;overflow:auto;font-family:var(--font-sans)}
|
||
.notes-overlay.open{transform:translateY(0)}
|
||
.overview{position:fixed;inset:0;background:rgba(10,12,18,.92);backdrop-filter:blur(12px);z-index:50;
|
||
display:none;padding:40px;overflow:auto}
|
||
.overview.open{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;align-content:start}
|
||
.overview .thumb{background:var(--surface);border:1px solid var(--border);border-radius:12px;
|
||
aspect-ratio:16/9;overflow:hidden;cursor:pointer;position:relative;color:var(--text-1);padding:16px;
|
||
font-size:11px;transition:transform .2s var(--ease)}
|
||
.overview .thumb:hover{transform:scale(1.04)}
|
||
.overview .thumb .n{position:absolute;top:8px;left:10px;font-weight:700;font-size:14px;color:var(--text-3)}
|
||
.overview .thumb .t{position:absolute;bottom:10px;left:14px;right:14px;font-weight:600;color:var(--text-1)}
|
||
|
||
/* ================= PRESENTER VIEW ================= */
|
||
/* Presenter view opens in a separate popup window (S key).
|
||
* All presenter styles are self-contained in the popup HTML generated by runtime.js.
|
||
* The audience window (this file) is NOT affected — it stays as normal deck view.
|
||
* Only the .notes class below is needed to hide speaker notes from audience. */
|
||
|
||
/* ================= UTILITY ================= */
|
||
.hidden{display:none!important}
|
||
.nowrap{white-space:nowrap}
|
||
.tr{text-align:right}.tc{text-align:center}.tl{text-align:left}
|
||
.uppercase{text-transform:uppercase;letter-spacing:.12em}
|
||
|
||
/* ================= PRINT ================= */
|
||
@media print{
|
||
.slide{position:relative;opacity:1!important;transform:none!important;page-break-after:always;height:100vh}
|
||
.deck-header,.deck-footer,.progress-bar,.notes-overlay,.overview{display:none!important}
|
||
}
|
||
|
||
</style>
|
||
<style>/* knowledge-arch-blueprint — cream paper + architectural blueprint style
|
||
family signatures kept: cream paper, drafting grid, rust ink, 2px ruled borders.
|
||
polish pass: Archivo drafting grotesque (Inter retired), sharp corners, shadows
|
||
removed (drawings are flat), contrast fixes, staggered entrance on transform+opacity. */
|
||
.tpl-knowledge-arch-blueprint{
|
||
--kb-bg:#F0EAE0;
|
||
--kb-ink:#1a1a1a;
|
||
--kb-ink2:#4f4b44;
|
||
--kb-ink3:#6f6a5f; /* was #8a8479: lifted to ~4.7:1 on cream for AA meta text */
|
||
--kb-rust:#B5392A;
|
||
--kb-rust-soft:rgba(181,57,42,.08);
|
||
--kb-line:#cec8be;
|
||
background:var(--kb-bg);
|
||
color:var(--kb-ink);
|
||
font-family:'Archivo',-apple-system,sans-serif;
|
||
}
|
||
.tpl-knowledge-arch-blueprint .slide{background:var(--kb-bg);color:var(--kb-ink);padding:64px 80px}
|
||
.tpl-knowledge-arch-blueprint .kb-grid-bg{position:absolute;inset:0;pointer-events:none;opacity:.35;background-image:linear-gradient(rgba(26,26,26,.06) 1px,transparent 1px),linear-gradient(90deg,rgba(26,26,26,.06) 1px,transparent 1px);background-size:48px 48px;mask-image:radial-gradient(ellipse at center,black 40%,transparent 85%)}
|
||
.tpl-knowledge-arch-blueprint .slide > *{position:relative;z-index:2}
|
||
.tpl-knowledge-arch-blueprint .kb-kicker{font-family:'IBM Plex Mono',monospace;font-size:12px;font-weight:600;letter-spacing:.28em;text-transform:uppercase;color:var(--kb-rust);margin-bottom:14px}
|
||
.tpl-knowledge-arch-blueprint .kb-h1{font-size:66px;font-weight:800;line-height:1.04;color:#111;margin:0 0 14px;letter-spacing:-.025em;text-wrap:balance}
|
||
.tpl-knowledge-arch-blueprint .kb-h1 span.rust{color:var(--kb-rust)}
|
||
.tpl-knowledge-arch-blueprint .kb-sub{font-size:19px;color:var(--kb-ink2);line-height:1.6;max-width:62ch}
|
||
.tpl-knowledge-arch-blueprint .kb-sub b{white-space:nowrap} /* keep URLs and bold runs from breaking mid-word */
|
||
.tpl-knowledge-arch-blueprint .kb-insight{display:inline-block;background:var(--kb-rust);color:#fff;border-radius:2px;padding:18px 22px;font-size:14px;font-weight:600;line-height:1.55;max-width:340px;border-left:6px double rgba(255,255,255,.55)}
|
||
.tpl-knowledge-arch-blueprint .kb-insight .kk{font-family:'IBM Plex Mono',monospace;font-size:10px;letter-spacing:.22em;opacity:.75;display:block;margin-bottom:8px;font-weight:600}
|
||
.tpl-knowledge-arch-blueprint .kb-section-label{font-family:'IBM Plex Mono',monospace;font-size:11px;font-weight:600;letter-spacing:.3em;text-transform:uppercase;color:var(--kb-ink3);margin:30px 0 12px;display:flex;align-items:center;gap:14px}
|
||
.tpl-knowledge-arch-blueprint .kb-section-label::after{content:'';flex:1;height:1px;background:var(--kb-line)}
|
||
.tpl-knowledge-arch-blueprint .kb-pipeline{display:flex;align-items:stretch;gap:14px;margin-top:24px}
|
||
.tpl-knowledge-arch-blueprint .kb-step{flex:1;border:2px solid #1a1a1a;border-radius:2px;padding:20px 18px;background:#FBF8F2;position:relative;min-height:178px;display:flex;flex-direction:column}
|
||
.tpl-knowledge-arch-blueprint .kb-step.hero{background:var(--kb-rust);border-color:#1a1a1a;color:#fff;flex:1.25;transform:translateY(-8px)}
|
||
.tpl-knowledge-arch-blueprint .kb-step-num{font-family:'IBM Plex Mono',monospace;font-size:10px;font-weight:600;letter-spacing:.22em;color:var(--kb-ink3);margin-bottom:8px;text-transform:uppercase}
|
||
.tpl-knowledge-arch-blueprint .kb-step.hero .kb-step-num{color:rgba(255,255,255,.72)}
|
||
.tpl-knowledge-arch-blueprint .kb-step-title{font-size:22px;font-weight:800;line-height:1.15;letter-spacing:-.01em;color:#111;margin-bottom:8px}
|
||
.tpl-knowledge-arch-blueprint .kb-step.hero .kb-step-title{color:#fff}
|
||
.tpl-knowledge-arch-blueprint .kb-step-body{font-size:13px;line-height:1.55;color:var(--kb-ink2);margin-top:auto}
|
||
.tpl-knowledge-arch-blueprint .kb-step.hero .kb-step-body{color:rgba(255,255,255,.9)}
|
||
.tpl-knowledge-arch-blueprint .kb-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:24px}
|
||
.tpl-knowledge-arch-blueprint .kb-card{background:#FBF8F2;border:2px solid #1a1a1a;border-radius:2px;padding:22px 24px}
|
||
.tpl-knowledge-arch-blueprint .kb-card h4{font-size:20px;font-weight:800;letter-spacing:-.01em;margin-bottom:6px}
|
||
.tpl-knowledge-arch-blueprint .kb-card p{font-size:14px;color:var(--kb-ink2);line-height:1.55}
|
||
.tpl-knowledge-arch-blueprint .kb-legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:22px;font-family:'IBM Plex Mono',monospace;font-size:12px;color:var(--kb-ink2)}
|
||
.tpl-knowledge-arch-blueprint .kb-legend .d{display:flex;align-items:center;gap:8px}
|
||
.tpl-knowledge-arch-blueprint .kb-legend .b{width:14px;height:14px;border:2px solid #1a1a1a;border-radius:1px}
|
||
.tpl-knowledge-arch-blueprint .kb-legend .b.rust{background:var(--kb-rust);border-color:#1a1a1a}
|
||
.tpl-knowledge-arch-blueprint .kb-footer{position:absolute;left:80px;right:80px;bottom:36px;display:flex;justify-content:space-between;font-family:'IBM Plex Mono',monospace;font-size:11px;color:var(--kb-ink3);letter-spacing:.18em;text-transform:uppercase;border-top:1px solid var(--kb-line);padding-top:16px}
|
||
.tpl-knowledge-arch-blueprint .kb-mono{font-family:'IBM Plex Mono',monospace}
|
||
.tpl-knowledge-arch-blueprint .kb-codebox{background:#1a1a1a;color:#f0eae0;border-radius:2px;padding:22px 26px;font-family:'IBM Plex Mono',monospace;font-size:14px;line-height:1.8;margin-top:20px;border:2px solid #1a1a1a}
|
||
.tpl-knowledge-arch-blueprint .kb-codebox .cm{color:#aaa496} /* comment tone lifted for AA on #1a1a1a */
|
||
.tpl-knowledge-arch-blueprint .kb-codebox .kw{color:#e8a87c}
|
||
.tpl-knowledge-arch-blueprint .kb-codebox .st{color:#b3d1bc}
|
||
.tpl-knowledge-arch-blueprint .kb-codebox .hl{color:#f3a99e;background:rgba(255,255,255,.08);padding:0 4px;border-radius:2px}
|
||
.tpl-knowledge-arch-blueprint .kb-big-num{font-family:'Archivo',sans-serif;font-size:188px;font-weight:900;line-height:.9;color:var(--kb-rust);letter-spacing:-.05em}
|
||
|
||
/* entrance: staggered rise, transform+opacity only */
|
||
@keyframes kb-rise{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
|
||
.tpl-knowledge-arch-blueprint .slide.is-active > *:not(.kb-grid-bg):not(.kb-footer){animation:kb-rise .6s var(--ease) both}
|
||
.tpl-knowledge-arch-blueprint .slide.is-active > *:nth-child(3){animation-delay:.06s}
|
||
.tpl-knowledge-arch-blueprint .slide.is-active > *:nth-child(4){animation-delay:.12s}
|
||
.tpl-knowledge-arch-blueprint .slide.is-active > *:nth-child(5){animation-delay:.18s}
|
||
@media (prefers-reduced-motion:reduce){
|
||
.tpl-knowledge-arch-blueprint .slide.is-active > *{animation:none!important}
|
||
}
|
||
</style>
|
||
<style>
|
||
/* Static-preview fallback (runtime.js is absent — keep every slide visible) */
|
||
.deck{height:auto;min-height:100vh;overflow:visible}
|
||
.slide{position:relative;inset:auto;opacity:1;pointer-events:auto;transform:none;height:100vh;page-break-after:always}
|
||
.deck-header,.deck-footer,.slide-number,.progress-bar,.notes-overlay,.overview{pointer-events:none}
|
||
.notes{display:none!important}
|
||
</style></head>
|
||
<body class="tpl-knowledge-arch-blueprint">
|
||
<div class="deck">
|
||
|
||
<!-- 1. COVER -->
|
||
<section class="slide is-active">
|
||
<div class="kb-grid-bg"></div>
|
||
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:40px;margin-bottom:44px">
|
||
<div>
|
||
<div class="kb-kicker">Product Management · Incident Retro Deck</div>
|
||
<h1 class="kb-h1" style="font-size:54px">Turn an incident retro into<br>a <span class="rust">learning deck</span>, like a Platform VP</h1>
|
||
<p class="kb-sub">The daemon-restart data bug: what broke, why, the fix on the table, and the one decision engineering, SRE, and leadership need to co-sign this week.</p>
|
||
</div>
|
||
<div class="kb-insight"><span class="kk">DECISION NEEDED</span>Ship the data-root guardrail before the next namespace migration — not another point patch.</div>
|
||
</div>
|
||
<div class="kb-section-label">Retro Arc · Decision → Measure</div>
|
||
<div class="kb-pipeline">
|
||
<div class="kb-step"><div class="kb-step-num">STEP 01</div><div class="kb-step-title">Decision needed</div><div class="kb-step-body">Which fix ships this sprint: patch the call sites, or remove the fallback entirely</div></div>
|
||
<div class="kb-step"><div class="kb-step-num">STEP 02</div><div class="kb-step-title">User pain</div><div class="kb-step-body">41 projects looked "deleted" for 12 minutes after a routine restart</div></div>
|
||
<div class="kb-step hero"><div class="kb-step-num">STEP 03 · CORE</div><div class="kb-step-title">Options & recommendation</div><div class="kb-step-body">Compare the narrow patch against the guardrail that closes the whole class</div></div>
|
||
<div class="kb-step"><div class="kb-step-num">STEP 04</div><div class="kb-step-title">Measure</div><div class="kb-step-body">MTTR, recurrence count, and CI catch-rate we'll track post-ship</div></div>
|
||
</div>
|
||
<div class="kb-footer"><span>Open Design · Platform Incident Retro</span><span>01 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 2. SECTION DIVIDER -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div style="margin:auto 0">
|
||
<div class="kb-kicker">Chapter One · Decision Needed</div>
|
||
<h1 class="kb-h1" style="font-size:92px">Ship the guardrail —<br><span class="rust">before</span> the next restart</h1>
|
||
<p class="kb-sub" style="font-size:24px;margin-top:20px">On June 14, a routine daemon restart under a stale namespace let 41 projects' SQLite files resolve against a cwd-relative fallback instead of the daemon's actual data root.<br>The only question left this sprint is <b>which fix we ship</b> — a patch, or a guardrail.</p>
|
||
</div>
|
||
<div class="kb-footer"><span>Section · Chapter 1</span><span>02 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 3. CONTENT 2-col -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div class="kb-kicker">User Pain · Options</div>
|
||
<h1 class="kb-h1" style="font-size:44px">12 minutes of "my projects vanished" × 41 teams</h1>
|
||
<div class="kb-grid-2">
|
||
<div class="kb-card">
|
||
<div class="kb-kicker" style="color:#6f6a5f">Option A</div>
|
||
<h4>Patch the call sites</h4>
|
||
<p>Fix the 9 known <span class="kb-mono">openDatabase(projectRoot)</span> calls to pass the resolved data root explicitly. Ships in two days — but the next engineer who adds a call site can reintroduce the same escape.</p>
|
||
</div>
|
||
<div class="kb-card" style="background:var(--kb-rust-soft);border-color:var(--kb-rust)">
|
||
<div class="kb-kicker">Option B · Recommended</div>
|
||
<h4>Remove the fallback entirely</h4>
|
||
<p>Delete the cwd-relative default from <span class="kb-mono">openDatabase</span> itself, so a missing data root fails loudly at startup instead of silently writing elsewhere. One migration, closes the whole bug class.</p>
|
||
</div>
|
||
</div>
|
||
<div class="kb-legend">
|
||
<div class="d"><span class="b"></span>Fast, narrow coverage · Option A</div>
|
||
<div class="d"><span class="b rust"></span>Slower, closes the class · Option B</div>
|
||
<div class="d">—— data path ┈┈ silent fallback (the bug)</div>
|
||
</div>
|
||
<div class="kb-footer"><span>Content · Options</span><span>03 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 4. CODE -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div class="kb-kicker">Tradeoffs · The Fix</div>
|
||
<h1 class="kb-h1" style="font-size:44px">Why "patch the sites" loses to "kill the fallback"</h1>
|
||
<p class="kb-sub">A per-site patch depends on every future engineer remembering the rule. Removing the fallback makes the rule impossible to violate — the daemon simply refuses to start with an unresolved data root.</p>
|
||
<pre class="kb-codebox"><span class="cm"># apps/daemon/src/db.ts — before vs after</span>
|
||
<span class="kw">function</span> openDatabase(projectRoot<span class="hl">?</span>) {
|
||
<span class="kw">const</span> root = projectRoot ?? <span class="st">cwd-relative default</span> <span class="cm">// silent escape</span>
|
||
<span class="kw">return</span> sqlite.open(root)
|
||
}
|
||
|
||
<span class="cm"># after: fallback deleted, root is required</span>
|
||
<span class="kw">function</span> openDatabase(root<span class="hl"> = RUNTIME_DATA_DIR</span>) {
|
||
<span class="kw">if</span> (!root) <span class="kw">throw</span> <span class="st">"missing data root — refuse to start"</span>
|
||
<span class="kw">return</span> sqlite.open(root)
|
||
}</pre>
|
||
<div class="kb-footer"><span>Content · Tradeoffs</span><span>04 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 5. DIAGRAM - SVG feedback loop -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div class="kb-kicker">Recommendation · System Diagram</div>
|
||
<h1 class="kb-h1" style="font-size:40px">One resolved root, three enforced checks</h1>
|
||
<svg viewBox="0 0 1200 520" style="width:100%;max-width:1200px;margin-top:20px" xmlns="http://www.w3.org/2000/svg">
|
||
<defs>
|
||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
|
||
<path d="M0,0 L10,5 L0,10 z" fill="#1a1a1a"/>
|
||
</marker>
|
||
<marker id="arrow-r" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
|
||
<path d="M0,0 L10,5 L0,10 z" fill="#B5392A"/>
|
||
</marker>
|
||
</defs>
|
||
<g font-family="Archivo, sans-serif" font-size="16" font-weight="700">
|
||
<!-- boxes -->
|
||
<rect x="40" y="180" width="200" height="120" rx="2" fill="#FBF8F2" stroke="#1a1a1a" stroke-width="2"/>
|
||
<text x="140" y="220" text-anchor="middle">Daemon start</text>
|
||
<text x="140" y="250" text-anchor="middle" font-size="12" font-weight="400" fill="#4f4b44">OD_DATA_DIR env in</text>
|
||
|
||
<rect x="300" y="180" width="200" height="120" rx="2" fill="#FBF8F2" stroke="#1a1a1a" stroke-width="2"/>
|
||
<text x="400" y="220" text-anchor="middle">Resolve root</text>
|
||
<text x="400" y="250" text-anchor="middle" font-size="12" font-weight="400" fill="#4f4b44">no cwd fallback allowed</text>
|
||
|
||
<rect x="560" y="160" width="220" height="160" rx="2" fill="#B5392A" stroke="#1a1a1a" stroke-width="2"/>
|
||
<text x="670" y="210" text-anchor="middle" fill="#fff" font-size="20">RUNTIME_DATA_DIR</text>
|
||
<text x="670" y="240" text-anchor="middle" font-size="12" font-weight="400" fill="rgba(255,255,255,.8)">single source of truth</text>
|
||
<text x="670" y="262" text-anchor="middle" font-size="12" font-weight="400" fill="rgba(255,255,255,.8)">SQLite · artifacts · plugins</text>
|
||
|
||
<rect x="840" y="180" width="200" height="120" rx="2" fill="#FBF8F2" stroke="#1a1a1a" stroke-width="2"/>
|
||
<text x="940" y="220" text-anchor="middle">Every caller</text>
|
||
<text x="940" y="250" text-anchor="middle" font-size="12" font-weight="400" fill="#4f4b44">openDatabase, artifacts, MCP</text>
|
||
|
||
<!-- forward arrows -->
|
||
<line x1="245" y1="240" x2="295" y2="240" stroke="#1a1a1a" stroke-width="2" marker-end="url(#arrow)"/>
|
||
<line x1="505" y1="240" x2="555" y2="240" stroke="#1a1a1a" stroke-width="2" marker-end="url(#arrow)"/>
|
||
<line x1="785" y1="240" x2="835" y2="240" stroke="#1a1a1a" stroke-width="2" marker-end="url(#arrow)"/>
|
||
|
||
<!-- feedback dashed -->
|
||
<path d="M 940 180 Q 940 80, 670 80 Q 400 80, 400 180" fill="none" stroke="#B5392A" stroke-width="2" stroke-dasharray="6 6" marker-end="url(#arrow-r)"/>
|
||
<rect x="580" y="58" width="180" height="30" rx="2" fill="#F0EAE0" stroke="#B5392A" stroke-width="1"/>
|
||
<text x="670" y="78" text-anchor="middle" fill="#B5392A" font-size="12">CI CHECK · blocks new fallbacks</text>
|
||
|
||
<!-- bottom feedback to sources -->
|
||
<path d="M 940 300 Q 940 420, 670 420 Q 140 420, 140 300" fill="none" stroke="#B5392A" stroke-width="2" stroke-dasharray="6 6" marker-end="url(#arrow-r)"/>
|
||
<rect x="560" y="400" width="220" height="30" rx="2" fill="#F0EAE0" stroke="#B5392A" stroke-width="1"/>
|
||
<text x="670" y="420" text-anchor="middle" fill="#B5392A" font-size="12">RESTART DRILL · every release, both namespaces</text>
|
||
</g>
|
||
</svg>
|
||
<div class="kb-footer"><span>Diagram · Recommendation</span><span>05 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 6. STATS -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div class="kb-kicker">Measure</div>
|
||
<h1 class="kb-h1" style="font-size:44px">What we track <span class="rust">after ship</span></h1>
|
||
<div style="display:grid;grid-template-columns:1.3fr 1fr 1fr;gap:24px;margin-top:28px;align-items:center">
|
||
<div style="text-align:center"><div class="kb-big-num">0</div><p style="font-family:'IBM Plex Mono',monospace;font-size:13px;color:#4f4b44;margin-top:6px;letter-spacing:.14em;text-transform:uppercase">Recurrences targeted across next 2 restart drills</p></div>
|
||
<div class="kb-card"><h4 style="color:var(--kb-rust)">-92%</h4><p>MTTR for data-path incidents once the CI guardrail lands (14m → 70s)</p></div>
|
||
<div class="kb-card"><h4 style="color:var(--kb-rust)">9 → 0</h4><p>Legacy fallback call sites remaining after the migration</p></div>
|
||
</div>
|
||
<div class="kb-grid-2" style="margin-top:18px">
|
||
<div class="kb-card"><h4>3 signals we watch</h4><p>Restart-drill pass rate, CI guardrail catches on PRs, and support tickets tagged "missing project."</p></div>
|
||
<div class="kb-card"><h4>Sign-off owners</h4><p>Platform infra and SRE co-sign the guardrail PR; engineering leadership signs off on the quarterly restart-drill cadence.</p></div>
|
||
</div>
|
||
<div class="kb-footer"><span>Content · Measure</span><span>06 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 7. CTA -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div class="kb-kicker">Next Step · The Ask</div>
|
||
<h1 class="kb-h1" style="font-size:52px">Approve the <span class="rust">guardrail PR</span> this week</h1>
|
||
<p class="kb-sub">One irreversible step: merge the fallback removal plus the CI check before the next namespace migration ships.</p>
|
||
<div class="kb-pipeline">
|
||
<div class="kb-step"><div class="kb-step-num">TODAY</div><div class="kb-step-title">Merge the guardrail PR</div><div class="kb-step-body">Removes the cwd-relative fallback from openDatabase</div></div>
|
||
<div class="kb-step"><div class="kb-step-num">THIS WEEK</div><div class="kb-step-title">Run the restart drill</div><div class="kb-step-body">Two concurrent namespaces, verify no silent fallback writes</div></div>
|
||
<div class="kb-step hero"><div class="kb-step-num">NEXT RELEASE · CORE</div><div class="kb-step-title">Ship the CI check</div><div class="kb-step-body">Blocks any new call site that recomputes a data root instead of receiving one</div></div>
|
||
<div class="kb-step"><div class="kb-step-num">ONGOING</div><div class="kb-step-title">Quarterly drill review</div><div class="kb-step-body">SRE reports pass rate to leadership every release cycle</div></div>
|
||
</div>
|
||
<div class="kb-footer"><span>CTA</span><span>07 / 08</span></div>
|
||
</section>
|
||
|
||
<!-- 8. THANKS -->
|
||
<section class="slide">
|
||
<div class="kb-grid-bg"></div>
|
||
<div style="margin:auto 0;text-align:center">
|
||
<div class="kb-kicker">Engineering · SRE · Leadership</div>
|
||
<h1 class="kb-h1" style="font-size:104px;margin-top:24px">sign <span class="rust">·</span> off</h1>
|
||
<p class="kb-sub" style="margin:0 auto;font-size:22px">Cross-functional agreement closes this retro: Platform, SRE, and Leadership all back <b class="nowrap">the guardrail</b>, not just the patch.</p>
|
||
</div>
|
||
<div class="kb-footer"><span>End of deck</span><span>08 / 08</span></div>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|