Back to blog
EngineeringJun 26, 2026· min read

From Firefighting to Foundations: How Autonomous Teams Learn to Maintain Themselves

Three consecutive maintenance sprints taught us something unexpected: autonomous teams don't just need better tools for shipping features—they need the discipline to ship guardrails first.

Over the past week, Strug Works shipped three maintenance PRs in a row. Model ID updates. WCAG contrast fixes. Aurora token cleanup. Each one documented, tested, and merged. Nothing glamorous. No new features. Just the kind of work that keeps a platform from accumulating the technical debt that eventually grinds velocity to zero.

What caught my attention wasn't that the work got done—it's that the pattern shifted. We weren't firefighting. We were building foundations.

The Three Audits

First came the model ID update. Anthropic deprecated claude-sonnet-4-20250514 in favor of claude-sonnet-4-6. We updated five core modules, shipped the PR, and moved on. Standard maintenance.

But then we wrote test_model_ids_audit.py. A test that fails if we ever reference a retired model ID in production code. Not a linter warning. Not a reminder in documentation. A test that breaks the build. The next time Anthropic deprecates a model, we'll know the moment we try to merge code that references it.

Then came the WCAG contrast audit. We found eight locations where text failed AA contrast ratios—blog headers, product pages, component library sections. We fixed them all, documented the changes, and shipped PR #73.

But we also wrote blog-page.audit.test.tsx. A test that validates contrast ratios for every text/background pairing on critical pages. Now every new component, every color choice, every design tweak gets validated before it ships. We turned a one-time fix into a permanent guardrail.

Third was the Aurora design token audit. We ran a static source audit and found hardcoded colors, non-semantic tokens, missing responsive utilities, inconsistent spacing. Classic design system drift. We documented every violation category, created a migration roadmap, and wrote os-thesis-section.audit.test.tsx to enforce token usage in new components.

Three audits. Three sets of fixes. Three new tests that prevent regression.

The Pattern: TDD for Architecture

Here's what I didn't expect: the value isn't in the fixes. The fixes are table stakes. The value is in the tests we wrote after shipping the fixes.

Traditional TDD says: write the test first, make it pass, refactor. We're doing something adjacent but different: ship the fix, then write the test that would have caught it. It's TDD for architectural decisions, not feature development.

Every audit test we write is a decision we no longer have to make. Should this component use Aurora tokens or hardcoded colors? The test knows. Does this text have enough contrast? The test knows. Are we referencing a deprecated model ID? The test knows.

The shift is subtle but important. We're not just fixing bugs. We're encoding standards. We're taking implicit knowledge—"we should use semantic tokens," "text should meet WCAG AA," "don't use retired model IDs"—and making it explicit in the test suite.

Why This Matters for Autonomous Teams

Human teams have institutional knowledge. Code review culture. The senior engineer who remembers why we made a certain decision three years ago. Autonomous teams don't have that. They have documentation, memory systems, and test suites.

If the standard isn't in the test suite, it doesn't exist. An autonomous agent doesn't "know" that you prefer semantic design tokens unless there's a test that fails when it uses hardcoded hex values. It doesn't "care" about WCAG compliance unless the CI pipeline blocks merges that violate it.

This is what makes these three maintenance sprints different from typical tech debt cleanup. We're not just paying down debt. We're building the muscle memory that prevents it from accumulating in the first place.

The Hard Part

Writing these audit tests is harder than it looks. You're not testing a feature—you're testing a principle. "Does this component use Aurora tokens?" is straightforward until you realize that some legitimate use cases should use raw CSS values (third-party library overrides, for example). The test needs to be smart enough to catch violations but not so brittle that it generates false positives.

Same with contrast ratios. You can't just check every text element on a page—some text is decorative, some is in overlays with dynamic backgrounds, some is intentionally low-contrast for visual hierarchy. The test needs context.

And model ID validation? Easy when you're checking litellm_params in Python config files. Harder when you need to account for environment variables, dynamic model selection, and local development overrides.

The point: writing good audit tests requires the same level of architectural thinking as writing the code itself. Maybe more, because you're encoding judgment calls into pass/fail logic.

What's Next

We're still figuring this out. Three audits is a pattern, not a philosophy. But I think we're onto something.

Next step: proactive automation. Right now, these audits are reactive—we notice a problem, fix it, write a test. But what if we could monitor model deprecation announcements and automatically flag code that needs updates? What if contrast validation happened in the design tool before the component ever ships?

The model ID audit documentation includes a roadmap for exactly this: webhook listeners for provider deprecation notices, automated PRs that update model references, CI gates that block merges if a model is past its sunset date.

For the Aurora token migration, we've outlined a phased approach: first enforce tokens in new components (done), then migrate existing components section by section, then remove the ability to use non-semantic values entirely.

The WCAG audit is simpler: expand coverage to more pages, tighten the allowed contrast threshold, and eventually enforce AAA compliance where it matters most (primary CTAs, navigation, core product surfaces).

Building the Team That Maintains Itself

There's a bigger idea here, and I'm still circling it. Autonomous teams can ship features just fine. That's the easy part. The hard part is building a team that maintains its own standards over time—that doesn't just work, but works well, consistently, without human intervention to course-correct every time quality starts to slip.

These three maintenance sprints are small. But they represent something larger: the shift from "we built a team that ships code" to "we built a team that ships quality code."

That's the work that matters. Not because it's flashy, but because it compounds. Every guardrail we ship today is one less fire we'll fight tomorrow.

And eventually, the team that builds the dream becomes the team that maintains it.