work-blog/articles/drafts/testing-telos.html
Gregory Gauthier 035cdbc051 feat(articles): add draft page for Testing Telos
Introduces an interactive HTML page in drafts/ explaining testing strategies via geometric shapes (triangle, bullseye, diamond, star). Includes embedded CSS for responsive design, SVG icons, and JavaScript for overview/detail view navigation.
2026-04-08 13:39:02 +01:00

362 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Testing Telos</title>
<style>
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Georgia, Cambria, "Times New Roman", serif;
background-color: #F5F0E8;
color: #3D2B1F;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
}
/* ─── Header ─── */
.page-header {
text-align: center;
padding: 2.5rem 1rem 1rem;
}
.page-header h1 {
font-size: 2.8rem;
font-weight: 700;
letter-spacing: 0.04em;
color: #3D2B1F;
margin-bottom: 0.3rem;
}
.page-header .tagline {
font-size: 1.1rem;
font-style: italic;
color: #6B5744;
letter-spacing: 0.02em;
}
/* ─── Overview Grid ─── */
#overview {
width: 100%;
max-width: 720px;
padding: 1rem;
transition: opacity 0.35s ease, transform 0.35s ease;
}
#overview.hidden {
opacity: 0;
transform: translateY(10px);
pointer-events: none;
position: absolute;
}
.quadrant-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 1.2rem;
aspect-ratio: 1 / 1;
}
.quadrant {
background: #FDFBF7;
border: 1.5px solid #D6CBBA;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 1.5rem 1rem;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
text-align: center;
}
.quadrant:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(61, 43, 31, 0.12);
border-color: #B8A48E;
}
.quadrant:active {
transform: translateY(0);
}
.quadrant svg {
width: 100px;
height: 100px;
margin-bottom: 1rem;
}
.quadrant .label {
font-size: 1.25rem;
font-weight: 700;
color: #3D2B1F;
margin-bottom: 0.25rem;
}
.quadrant .subtitle {
font-size: 0.9rem;
font-style: italic;
color: #8B7560;
}
/* ─── Detail View ─── */
#detail {
width: 100%;
max-width: 780px;
padding: 1rem 1.5rem 3rem;
transition: opacity 0.35s ease, transform 0.35s ease;
}
#detail.hidden {
opacity: 0;
transform: translateY(10px);
pointer-events: none;
position: absolute;
}
.back-link {
display: inline-block;
font-size: 1rem;
color: #6B5744;
text-decoration: none;
cursor: pointer;
margin-bottom: 1.5rem;
transition: color 0.2s ease;
}
.back-link:hover {
color: #3D2B1F;
}
.detail-header {
display: flex;
align-items: center;
gap: 1.2rem;
margin-bottom: 0.4rem;
}
.detail-header svg {
width: 64px;
height: 64px;
flex-shrink: 0;
}
.detail-header h2 {
font-size: 2rem;
font-weight: 700;
color: #3D2B1F;
}
.detail-emphasis {
font-size: 1.05rem;
font-style: italic;
color: #8B7560;
margin-bottom: 2rem;
padding-left: 76px; /* align with header text */
}
.panel {
background: #FDFBF7;
border: 1px solid #D6CBBA;
border-radius: 8px;
padding: 1.4rem 1.6rem;
margin-bottom: 1.2rem;
}
.panel h3 {
font-size: 1.15rem;
font-weight: 700;
margin-bottom: 0.6rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.panel h3 .panel-icon {
font-style: normal;
font-size: 1.1rem;
}
.panel p {
font-size: 1.02rem;
line-height: 1.7;
color: #4A3728;
}
/* Panel accent strips */
.panel-purpose { border-left: 4px solid #B8860B; }
.panel-strategy { border-left: 4px solid #6B8E6B; }
.panel-risk { border-left: 4px solid #A0522D; }
.panel-confidence { border-left: 4px solid #5B7B8A; }
/* ─── Responsive ─── */
@media (max-width: 560px) {
.page-header h1 { font-size: 2rem; }
.quadrant svg { width: 70px; height: 70px; }
.quadrant .label { font-size: 1.05rem; }
.quadrant .subtitle { font-size: 0.8rem; }
.detail-emphasis { padding-left: 0; }
.detail-header { flex-direction: column; align-items: flex-start; gap: 0.6rem; }
}
</style>
</head>
<body>
<header class="page-header">
<h1>Testing Telos</h1>
<p class="tagline">A shape for every purpose; a purpose for every shape</p>
</header>
<!-- ════════ OVERVIEW ════════ -->
<section id="overview">
<div class="quadrant-grid">
<div class="quadrant" onclick="showDetail('triangle')">
<svg viewBox="0 0 100 100" aria-hidden="true">
<polygon points="50,12 90,88 10,88" fill="#C9963A" stroke="#A07828" stroke-width="2" stroke-linejoin="round"/>
</svg>
<div class="label">Feature Iteration</div>
<div class="subtitle">Emphasis downward</div>
</div>
<div class="quadrant" onclick="showDetail('bullseye')">
<svg viewBox="0 0 100 100" aria-hidden="true">
<circle cx="50" cy="50" r="44" fill="#D4B896" stroke="#A07828" stroke-width="1.5"/>
<circle cx="50" cy="50" r="29" fill="#C4A276" stroke="#8B7560" stroke-width="1.5"/>
<circle cx="50" cy="50" r="14" fill="#A0522D" stroke="#7A3E20" stroke-width="1.5"/>
</svg>
<div class="label">Invariance Testing</div>
<div class="subtitle">Emphasis inward</div>
</div>
<div class="quadrant" onclick="showDetail('diamond')">
<svg viewBox="0 0 100 100" aria-hidden="true">
<polygon points="50,6 94,50 50,94 6,50" fill="#7BA085" stroke="#5A7A63" stroke-width="2" stroke-linejoin="round"/>
</svg>
<div class="label">Cross-Cutting Changes</div>
<div class="subtitle">Emphasis outward</div>
</div>
<div class="quadrant" onclick="showDetail('star')">
<svg viewBox="0 0 100 100" aria-hidden="true">
<polygon points="50,4 61,36 96,36 68,58 78,92 50,72 22,92 32,58 4,36 39,36" fill="#C07060" stroke="#8B4040" stroke-width="2" stroke-linejoin="round"/>
</svg>
<div class="label">Targeted Concerns</div>
<div class="subtitle">Emphasis spiked</div>
</div>
</div>
</section>
<!-- ════════ DETAIL VIEW ════════ -->
<section id="detail" class="hidden">
<a class="back-link" onclick="showOverview()">&#8592; Back to overview</a>
<div class="detail-header">
<div id="detail-shape"></div>
<h2 id="detail-title"></h2>
</div>
<p class="detail-emphasis" id="detail-emphasis"></p>
<div class="panel panel-purpose">
<h3><span class="panel-icon">&#9670;</span> Purpose</h3>
<p id="panel-purpose-text"></p>
</div>
<div class="panel panel-strategy">
<h3><span class="panel-icon">&#9670;</span> Testing Strategy</h3>
<p id="panel-strategy-text"></p>
</div>
<div class="panel panel-risk">
<h3><span class="panel-icon">&#9670;</span> Risk Distribution</h3>
<p id="panel-risk-text"></p>
</div>
<div class="panel panel-confidence">
<h3><span class="panel-icon">&#9670;</span> Confidence Signals</h3>
<p id="panel-confidence-text"></p>
</div>
</section>
<script>
const data = {
triangle: {
title: "Feature Iteration",
emphasis: "Emphasis downward \u2014 build confidence from the base up",
shape: `<svg viewBox="0 0 100 100" width="64" height="64"><polygon points="50,12 90,88 10,88" fill="#C9963A" stroke="#A07828" stroke-width="2" stroke-linejoin="round"/></svg>`,
purpose: "Validating new or changed user-facing functionality. The new behavior is the subject under test. Risk is localized and forward-looking: you are asking whether the thing you just built actually works as intended.",
strategy: "Heavy emphasis on unit tests at the base. Integration tests validate that the new feature interacts correctly with existing components. A thin layer of end-to-end tests confirms the user-facing workflow. The traditional pyramid shape applies most naturally here \u2014 this is the category the pyramid was designed for.",
risk: "Risk is concentrated around the new code. Failures are usually local and predictable. Adjacent components may be affected through integration points, but the blast radius is bounded. You generally know where to look when something breaks.",
confidence: "New behavior is exercised thoroughly at the unit level. Integration boundaries are tested. At least one end-to-end path covers the primary user workflow. Edge cases are captured in lower-level tests. When the base is solid, the upper layers provide confirmation, not discovery."
},
bullseye: {
title: "Invariance Testing",
emphasis: "Emphasis inward \u2014 protecting a core that must remain stable",
shape: `<svg viewBox="0 0 100 100" width="64" height="64"><circle cx="50" cy="50" r="44" fill="#D4B896" stroke="#A07828" stroke-width="1.5"/><circle cx="50" cy="50" r="29" fill="#C4A276" stroke="#8B7560" stroke-width="1.5"/><circle cx="50" cy="50" r="14" fill="#A0522D" stroke="#7A3E20" stroke-width="1.5"/></svg>`,
purpose: "Proving that everything that worked before still works after an environmental or structural change. This includes infrastructure upgrades, dependency updates, and refactoring. The desired outcome is no observable change \u2014 the telos is invariance itself.",
strategy: "Emphasis flows inward toward the core. Existing regression suites are the primary tool. Characterization tests and contract tests matter greatly. Run everything; watch for unexpected failures in unexpected places. The goal is not to exercise new behavior but to confirm the absence of unintended change.",
risk: "Risk is diffuse. Failures appear in surprising locations because the change is to the substrate, not to specific features. The most dangerous failures are subtle behavioral changes that don\u2019t cause outright errors \u2014 things that silently drift rather than loudly break.",
confidence: "Full regression suite passes. No behavioral drift detected. Performance benchmarks remain stable. Dependency compatibility is verified across the integration surface. Confidence comes from breadth of coverage, not depth on any single feature."
},
diamond: {
title: "Cross-Cutting Structural Changes",
emphasis: "Emphasis outward \u2014 broadly general, no layer is privileged",
shape: `<svg viewBox="0 0 100 100" width="64" height="64"><polygon points="50,6 94,50 50,94 6,50" fill="#7BA085" stroke="#5A7A63" stroke-width="2" stroke-linejoin="round"/></svg>`,
purpose: "Validating changes that permeate the entire system with roughly equal intensity \u2014 schema migrations, data model changes, cross-cutting architectural modifications. These changes have a temporal dimension that others lack: you must validate the before-state, the migration itself, and the after-state.",
strategy: "No single layer dominates. Unit tests verify the new structure. Integration tests confirm data flows correctly across the transition. End-to-end tests validate that the system works in both the pre- and post-migration state. Backward compatibility and rollback are first-class concerns. The testing effort is as broad as the change itself.",
risk: "Risk is broadly distributed. Every layer of the system is potentially affected. The migration process itself is a distinct source of risk, separate from the before and after states. A failure at any level can cascade unpredictably because the change is structural, not localized.",
confidence: "Both old and new data work correctly. The migration is reversible and has been tested in both directions. No layer of the system is untested. The temporal sequence \u2014 before, during, after \u2014 has been validated as a continuous path, not just as isolated snapshots."
},
star: {
title: "Targeted Non-Functional Concerns",
emphasis: "Emphasis spiked \u2014 each point is a specific vector of concern",
shape: `<svg viewBox="0 0 100 100" width="64" height="64"><polygon points="50,4 61,36 96,36 68,58 78,92 50,72 22,92 32,58 4,36 39,36" fill="#C07060" stroke="#8B4040" stroke-width="2" stroke-linejoin="round"/></svg>`,
purpose: "Validating specific vectors of concern \u2014 security attack surfaces, performance bottlenecks, compliance posture. The question is not \u201Cdoes it work?\u201D but \u201Cis it safe, fast, and compliant?\u201D Each point of the star represents a distinct risk that must be probed with specialized tools and techniques.",
strategy: "Each point of the star is probed independently with its own methodology. Security: scanning, penetration testing, audit trail validation. Performance: load testing, profiling, benchmarking against thresholds. Compliance: regulatory checklists, data handling verification. The pass/fail criteria are thresholds and compliance checks, not functional assertions.",
risk: "Risk is spiked and specific. Each concern has its own attack vector or failure mode. Failures don\u2019t radiate predictably \u2014 they cluster around specific vulnerability points. A performance bottleneck and a security flaw may coexist in the same system without any relationship to each other.",
confidence: "Each identified risk vector has been specifically addressed. Thresholds are met. Scans are clean. Audit trails are complete. There is no single comprehensive signal \u2014 confidence is the aggregate of multiple independent probes, each confirming that its particular concern has been satisfied."
}
};
const overview = document.getElementById('overview');
const detail = document.getElementById('detail');
function showDetail(key) {
const d = data[key];
document.getElementById('detail-shape').innerHTML = d.shape;
document.getElementById('detail-title').textContent = d.title;
document.getElementById('detail-emphasis').textContent = d.emphasis;
document.getElementById('panel-purpose-text').textContent = d.purpose;
document.getElementById('panel-strategy-text').textContent = d.strategy;
document.getElementById('panel-risk-text').textContent = d.risk;
document.getElementById('panel-confidence-text').textContent = d.confidence;
overview.classList.add('hidden');
setTimeout(() => {
detail.classList.remove('hidden');
window.scrollTo({ top: 0, behavior: 'smooth' });
}, 100);
}
function showOverview() {
detail.classList.add('hidden');
setTimeout(() => {
overview.classList.remove('hidden');
window.scrollTo({ top: 0, behavior: 'smooth' });
}, 100);
}
</script>
</body>
</html>