Selection: Vanilla HTML/CSS/JavaScript in a single self-contained file. No framework, no build step, no external JS libraries.
The existing course demo
(course_materials/demos/data-control-vulnerability.html) is
a 1,019-line self-contained HTML file with zero external JS
dependencies. This is the established pattern in this repo and it's the
right pattern for several reasons:
npm install,
no lockfile drift, no CVEs, nothing to break between now and class
tomorrowcourse_materials/demos/ and add a website wrapperdata-control-vulnerability demo, so follow-on demos benefit
from consistency| Alternative | Rejected because |
|---|---|
| React/Vite | Build step overhead; framework learning curve during a same-day build; heavier for deployment |
| Svelte | Same as React but even less familiar to this project |
| D3.js | Powerful but adds ~250KB CDN dependency; visualizations we need (histograms, bar charts, table filtering) are simple enough to do with raw SVG or Canvas |
| Chart.js | Simpler than D3 but still an external dependency; adds a CDN failure point; our charts need custom animation/interaction that doesn't fit Chart.js idioms cleanly |
| Observable notebook | Not podium-friendly UX; looks like a notebook, not a presentation |
All four interactive elements from brainstorm.md can be
implemented with vanilla DOM + SVG manipulation:
The Laplace mechanism for differential privacy adds noise drawn from Laplace(0, Δf/ε), where Δf is the sensitivity of the query and ε is the privacy budget.
JavaScript implementation (verified working):
function laplaceNoise(epsilon, sensitivity = 1) {
const scale = sensitivity / epsilon;
const u = Math.random() - 0.5;
return -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
}Inverse CDF sampling. ~5 lines. No library needed.
For the epsilon slider demo:
This range maps naturally to the "privacy budget dial" narrative from the podcast.
For the demos, we'll assume sensitivity = 1 (a count query where any one individual can change the count by at most 1). This is the standard simple case and avoids the pedagogical complexity of explaining sensitivity before students have grasped the core concept.
For a bucket count of N people with noise drawn from Laplace(0, 1/ε):
This is exactly the pedagogical payoff we want.
Act 2 — Medical records + voter list
Act 3 — k-anonymity dataset
Act 4 — Salary/population histogram
Act 6 — Small community demographics
The script for each section will draw directly from the podcast transcript progression, lightly adapted for visual presentation (shorter sentences, callouts, key phrases). This is custom content, not scraped.
course_materials/demos/differential-privacy-explainer.html
(the self-contained 1-file demo)website/demos/differential-privacy-explainer/index.html
(iframe wrapper with course chrome)The website deploys via scripts/deploy-website.sh (based
on repo pattern). The demo needs to live in a path that gets copied into
the deployed site. Two options:
Copy the self-contained HTML into the deployed
tree — the existing deploy process handles
website/demos/{name}/ wrapper pages, but the actual demo
file is referenced via relative path
../../course_materials/demos/data-control-vulnerability.html.
This relative path must resolve correctly in deployment.
Verify deployment path — check
.docs/website-deployment.md during Plan phase to confirm
the exact deployment mechanism and ensure the artifact will be publicly
accessible.
Public URL will be:
https://dallaselleman.github.io/cyb-4203-6203-spring-2026/demos/differential-privacy-explainer/
High confidence that this stack can deliver all four interactive elements + 8 narrative sections in a single-day build: