What Went Wrong First
We planned 155 points. We shipped 42.
That sounds like failure, and it was — a planning failure. Our velocity is 38 points per sprint, validated across 3 sprints. We committed to 4x our capacity because infrastructure stories feel smaller than they are. An Architecture Decision Record forced the reckoning: cut 113 points of UI tab work and focus on what the platform actually needs before any new features get built.
The hardest part wasn't cutting scope. It was admitting that 7 new browser tabs don't matter if your API serves HTTP in production.
What We Actually Built
Sprint 9 was infrastructure-first. Every story was foundational work that has to land before Sprint 10's feature tabs can exist.
TLS termination — We were running HTTP-only. In 2026. The fix: nginx reverse proxy on port 443, self-signed cert generation for dev, certbot auto-renewal for production, HSTS headers at both the nginx and Express middleware layers. Defense in depth, not just a checkbox.
Test coverage for 42 untested services — 42 of 144 TypeScript services had zero test files. We wrote 171 tests across 6 categories (route handlers, API clients, audio pipeline, engagement analytics, utilities, error paths). The pattern: data-driven test arrays with for-of iteration. One compact file covers 12+ modules.
Accessibility foundations — Zero ARIA attributes across the entire React UI. We ran a static WCAG audit, found 2 real violations (div-based navigation without semantic nav, checkbox inputs without labels), fixed both, and created 4 shared components: EmptyState, ErrorState, LoadingSkeleton, ErrorBoundary. These exist before Sprint 10 builds 7 new tabs on top of them.
OpenAPI specification — 219 REST endpoints with zero documentation. We created a 300-line OpenAPI 3.0.3 YAML spec, added Swagger UI at /api-docs via CDN (no npm dependency), and wrote schema validation tests that check $ref resolution and endpoint completeness.
Patterns You Can Steal
Data-driven coverage tests. When you have 42 untested modules, don't write 42 test files. Write one file with a module descriptor array and iterate:
const modules = [
{ file: 'linkedin-api.ts', className: 'LinkedInAPI' },
{ file: 'reddit-api.ts', className: 'RedditAPI' },
];
for (const mod of modules) {
it(`should export ${mod.className}`, () => {
const content = fs.readFileSync(path.join(DIR, mod.file), 'utf-8');
expect(content).toMatch(new RegExp(`export class ${mod.className}`));
});
}
171 tests from 6 files. Structural validation without runtime instantiation.
Blog voice rules as code. After community feedback about our retrospective blogs reading like success theatre, we codified 6 editorial rules into a test-driven validator:
function validateBlogVoiceRules(blog: string) {
// Rule 1: First H2 must mention failure/challenge
// Rule 2: No internal ticket IDs in prose (strip code blocks first)
// Rule 3: No provenance tables
// Rule 4: No streak metrics as achievements
// Rule 5: Must include reusable patterns section
}
TDD caught 2 real bugs in the validator itself — the H2 detection logic and code block filtering both had edge cases.
Sidecar verification via YAML parse. You can validate Docker Compose service definitions without running containers:
const compose = parseYaml(fs.readFileSync('docker-compose.v3.yml', 'utf-8'));
const tts = Object.keys(compose.services).find(s => s.includes('tts'));
expect(tts).toBeDefined();
expect(content).toMatch(/8500/); // port check
CI-friendly config validation. Actual container testing is a separate concern.
What 359 New Tests Taught Us
We went from 4,394 tests to 4,753. Every test was written test-first through the full TDD cycle (RED → VERIFY → GREEN → REFACTOR → VALIDATE → DONE). The most valuable insight: static source analysis of React components catches real accessibility violations without needing a browser. Checking for dangerouslySetInnerHTML, missing aria-label, and overflow-hidden patterns via regex is surprisingly effective as a regression gate.
What's Next
Sprint 10a has 7 V3 UI tabs waiting for the accessibility and shared component foundations we just built. Sprint 10b has load testing, monitoring, backup/DR, and the program retrospective. The platform is now production-deployable — TLS, documented API, accessible UI, 4,753 tests. The remaining work is features, not infrastructure.
This post is part of the ORCHESTRATE Agile Suite series documenting AI-assisted development with full DD TDD methodology.
Top comments (0)