What Does a Good Spec File Look Like?

Most legacy government systems exist in a state of profound documentation poverty. The knowledge lives in the heads of retiring employees, in COBOL comments from 1987, in binders that may or may not reflect current behavior. Against this baseline, the question of what makes a “good” spec file takes on different dimensions than it might in greenfield development.

Common Elements

Any spec worth writing answers the fundamental question: what are we building and why? Beyond that, good specs share a few specific characteristics:

Clear success criteria. Not just features, but how you’ll know the thing works. This matters especially when AI agents are generating implementations—they need something concrete to validate against.

Constraints and boundaries. What’s out of scope. What technologies or patterns to use or avoid. Performance requirements. AI tools are prone to scope creep and assumption-making without explicit boundaries.

Examples of expected behavior. Concrete inputs and outputs, edge cases, error states. These serve as both specification and implicit test cases.

Context about the broader system. How this piece fits into what exists. AI assistants lack awareness of surrounding code and architectural decisions unless you tell them.

The SpecOps Context

When modernizing legacy government systems, specs serve a different purpose than typical development documentation. They’re not just implementation guides—they are artifacts that preserve institutional knowledge. This changes what “good” looks like.

A SpecOps specification document must work for multiple audiences simultaneously: domain experts who verify that the spec captures policy intent, software developers and AI coding agents who need precision to generate correct implementations, and future humans who need to understand why the system behaves a certain way years from now—possibly after everyone currently involved has moved on.

That last audience is the one most spec formats neglect entirely.

Three States, Not One

Legacy system specs can’t just describe “what the system does.” They need to distinguish between:

  • Current system behavior—what the legacy code actually does today, bugs and all
  • Current policy requirements—what the system should do according to governing statutes and regulations
  • Technical constraints—what the system cannot do regardless of policy, due to missing integrations or platform limitations
  • These three things can be in alignment or tension at any moment. And that alignment can shift over time without the code changing—a policy update tomorrow can transform compliant behavior into a violation.

    Known Deviation Patterns

    Consider the example of a benefits system that should verify income against a state tax agency records, but the legacy system only captures self-reported income because the integration with the tax agency was never built. A good spec would make this explicit:

    Policy requirement: Per [directive], applicant income must be verified against tax agency records prior to benefit approval.

    Current implementation: Self-reported income only. Applicant provides income information on Form X.

    Deviation reason: No interface to tax agency income verification service exists. Integration requested in 2019, not funded.

    Modernization note: Modern implementation should include tax agency income verification integration.

    This surfaces the gap, documents why it exists, and gives the modernization effort clear direction—without pretending the legacy system does something it doesn’t.

    Explicit Ambiguity as a Feature

    There’s something that seems almost radical about a methodology that says write down what you don’t know. Traditional documentation can project false confidence. It often describes how things should work and quietly omits the messy parts.

    A spec that explicitly marks areas of tension or uncertainty is more honest, more useful for risk assessment, and a better starting point for modernization. It’s an invitation for future clarification rather than a false endpoint.

    A spec with unresolved tension is better than no reviewable documentation at all. 

    Policy Grounding

    Government system specs need explicit links to authorizing statutes, regulations, or directives. Not just “these items are excluded from income calculations” but “per 42 USC § 1382a, the following items are excluded from income calculations”

    This is the why that survives personnel turnover. It’s what allows future teams to evaluate whether behavior that was correct five years ago still aligns with current policy.

    Decision Records

    When domain experts verify a spec, they make judgment calls—especially where legacy behavior diverges from current policy understanding. Those decisions need to be captured in the spec, not in a separate document that gets lost.

    The spec becomes the repository of institutional reasoning, not just institutional behavior.

    Accessible or Precise?

    The SpecOps approach says that specs should be “readable by domain experts while detailed enough to guide implementation.” This is genuinely hard.

    Options include stratified specs (plain-language summaries with expandable technical detail), executable specs (written as tests that are simultaneously human-readable and machine-verifiable), or annotated specs (a single verbose document where technical precision is explained inline).

    Given that the spec is meant to be the source of truth that outlasts implementations, keeping everything in one artifact—even at the cost of verbosity—reduces the risk of layers drifting apart over time.

    The Road Ahead

    We’re still in early days. Questions remain open:

    • How granular should policy references be?
    • What’s the right way to represent known deviations?
    • How should specs age—versioning, or is git history enough?
    • What level of detail helps AI agents versus adding noise?

    These will get answered empirically as more agencies adopt the approach. The methodology will evolve. The important thing is to start—to surface questions that were previously invisible, to give future teams something to interrogate rather than nothing at all.

    Because the knowledge is what matters. Everything else is implementation details.

    #ai #artificialIntelligence #chatgpt #governmentServices #legacySystems #systemModernization

    Big bang rewrites drain budgets and burn out teams.
    Modernization works best in stages.

    Lessons from distributed systems show how modular monoliths, feature toggles, and the strangler pattern make change sustainable.

    https://www.woodruff.dev/system-modernization-without-the-burnout-lessons-from-distributed-systems/

    #SystemModernization #SoftwareArchitecture

    System Modernization Without the Burnout: Lessons from Distributed Systems - Chris Woody Woodruff | Fractional Architect

    If you're looking for support in successfully migrating your legacy system, I would love to help your organization through this process. Let's connect and explore how I can assist you. You can contact me directly via my contact page here: https://www.woodruff.dev/contact/ The Dreaded “Big-Bang Rewrite” Every developer has heard the horror story: the company that

    Chris Woody Woodruff | Fractional Architect - Just Stuff from Woody

    The Quiet Crisis in Legacy System Modernization

    Government agencies have started experimenting with AI—particularly large language models (LLMs)—to accelerate the long-standing problem of modernizing legacy systems. A recent MITRE analysis, Legacy IT Modernization with AI, shows early promise. LLMs can be used to extract logic from old codebases and generate “intermediate representations” that help teams refactor or rewrite aging systems. It’s not a perfect solution, and it still requires human oversight, but it’s a serious step forward.

    So far, the conversation on AI-assisted legacy modernization has centered on large, mission-critical federal systems—mainframe applications that support tax processing, logistics, or entitlement programs. But this focus overlooks a vast and growing problem: the thousands of small, back-office systems that keep state and local governments running. These applications don’t often make headlines, but they quietly power licensing, payroll, casework, and many other daily operations.

    Many of these systems are written in obscure, decades-old languages (think MS Access). Documentation is sparse or nonexistent. The people who built and maintained them are retiring. And the government’s ability to recruit and retain technical staff has not kept pace with demand. What’s more, the sheer number of these systems—and the institutional knowledge they depend on—makes traditional modernization approaches slow and expensive.

    The MITRE report provides a useful proof point: AI can help accelerate modernization. But that benefit needs to reach beyond a few flagship systems. If modernization efforts stay focused only at the federal level or only on the biggest programs, governments at every level will be stuck maintaining outdated software with dwindling staff and rising risk.

    To meet this challenge, governments needs a broader approach. That means funding, staffing, and supporting modernization efforts that include every level of government—not just those at the federal level. It means experimenting with AI-assisted refactoring tools on a wider range of systems. And it means ensuring that institutional knowledge doesn’t retire out of reach before the code is made maintainable again.

    AI won’t solve legacy modernization on its own. But it’s the first tool in a long time that changes the speed and scale of what’s possible. We should use it—everywhere we can.

    #AI #ChatGPT #governmentServices #legacySystems #systemModernization

    Most of the patterns we use (knowingly or not) to guide digital modernization work in government come from the world of software development. We are drawn to these patterns because they are widely used and well understood in the software world, and they enable us to think about complex problems in ways that are easier to understand. We also typically think of digital modernization work as primarily work that revolves around software and technology.

    In practice, these patterns do not always work well (or as well as we think they should) because a big chunk of the hard work of doing digital modernization in government is organizational, legal, and bureaucratic. Software development patterns don’t really help with these things all that much. The change we seek is simply beyond them.

    The Strangler Fig Pattern is a software development pattern that is well known to people in the world of civic tech, and has inspired government digital service teams for many years. It is one of the most widely known pattern for digital service teams in government because it offers one way to migrate from an old legacy system to a new software solution — a very common challenge in government.*

    One of the drawbacks of the Strangler Fig Pattern that I have seen is that using it successfully can require lots of time. Finding the seams in legacy application that you can break off and build out on a new technical stack is often very complex (and contentious). Efforts to use this approach sometimes stall after the migration to a new system has begun, but before it is finished. This sometimes has the effect of leaving organizations in the unenviable position of having multiple systems in place underpinning a service and never fully completing the transition away from the older one.**

    Another very common pattern used in government digital work is the Facade Pattern, an approach that hides the complexity of a particular service or function behind a friendlier front-end.*** Some common examples of the Facade Pattern in action can be seen when digital teams:

    • Create a digitized version of a form that on submission gets converted into a PDF version of a paper form that then goes through the same (or similar) review and approval process as paper forms.
    • Use RPA tools and applications to automate existing business process steps — like in procurement processes — speeding them up and (potentially) reducing the errors resulting from human data entry but keeping the same basic steps of the process in place.
    • Leverage LLMs to simplify or summarize complex or disparate information without changing the structure, quality, or location of that source data.

    All of these uses of the Facade Pattern can result in a better experience for the people inside government or those that depend on government services, and all are worthy of investing time and energy into under the right circumstances. But none of these examples change the fundamental issues that can make service delivery more challenging. They just make changes at the epidermal level of government organizations. Sometimes this is enough, but where do we turn for patterns when we aspire to more fundamental change?

    The book, Platformland, by Richard Pope, came across my radar as I started thinking about the inadequacy of commonly used patterns for digital modernization. It’s a book full of really good ideas about what public digital services can be, and it’s organized around a set of patterns that can be used to build what he refers to as the “next generation of public services.” It’s full of really useful ideas and observations that will assist many of the people working in public sector organizations today to lay the groundwork for better digital services.

    For those of us working to modernize the digital infrastructure of government, we need new patterns that can help us as we pursue true digital modernization. This terrific new book offers a compelling and useful set of new patterns we can start to use.

    For a more comprehensive picture of software patterns specifically focused on legacy system migration, check out the book Monolith to Microservices, by Sam Newman.

    ** Some more recent work by the team that pioneered the Strangler Fig pattern for modernizing large legacy systems are now looking at Generative AI as a way to potentially speed up the process.

    *** If you think I’m misapplying the facade pattern to these examples, I’d love to have you share your thoughts in a comment.

    https://civic.io/2024/09/09/searching-for-patterns-in-digital-modernization/

    #civictech #governmentServices #legacySystems #softwarePatterns #systemModernization

    bliki: Strangler Fig

    Inspired by the strangler figs in Australia, a strangler fig application gradually draws behavior out of its host legacy application

    martinfowler.com