Self-Describing Systems: Software That Explains Itself

Self-Describing Systems: Software That Explains Itself

Post 3 of "The Common Language" series

In my previous post, I argued that text is the only universal interface between humans and AI. But text alone isn't enough. A folder full of markdown files is better than a folder full of PowerPoint slides, but it's still just a folder. Disconnected. Unstructured. Missing the relationships that give information meaning. The next step is harder: systems that describe themselves completely, from requirements through implementation through deployment through runtime. Everything connected. Everything traceable. Everything accessible to both human and artificial intelligence.

This is what I call self-describing systems. And almost nobody has them.

The Fragmentation Problem

Let me describe what I typically find when I join a project.

Requirements live in Confluence, Jira, SharePoint, or someone's email. Often all four. The "official" requirements document was last updated eighteen months ago. The actual requirements exist as a patchwork of ticket comments, meeting notes, and tribal knowledge.

Architecture exists as a Visio diagram or a whiteboard photo. Sometimes a PowerPoint deck from the original project pitch. The diagram shows the system as it was designed three years ago, not as it exists today. The reasoning behind architectural decisions lives in the heads of people who may no longer be on the team.

Code is in Git, which is good. But the connection between code and requirements is manual at best. You can trace a commit to a ticket number if someone remembered to include it. You cannot easily answer "which code implements this business capability" or "which requirements are affected if I change this module."

Configuration is scattered across cloud consoles, environment variables, property files, and secrets managers. Some is in version control. Some is not. The complete picture of how the system is configured exists nowhere.

Deployment might be automated, might be manual, might be a mix. The pipeline definition, if it exists, describes the mechanics but not the intent. Why do we deploy in this order? What are the dependencies? What should we check before promoting to production?

Runtime behavior generates logs that flow into various systems. Metrics go to monitoring dashboards. Traces go somewhere else. Connecting a production incident to the code that caused it to the requirement it was supposed to fulfill requires archaeology.

This fragmentation isn't laziness. It's the natural result of using different tools for different purposes without a unifying structure. Each tool optimizes for its own domain. None of them optimize for the connections between domains.

Why This Matters for AI

A human expert can navigate this fragmentation. With enough experience and context, they build a mental model that connects the pieces. They know that ticket PROJ-1234 relates to the authentication module, which was designed that way because of a decision made in the March 2022 architecture review, which is documented in that one Confluence page if you know where to look.

This knowledge is valuable. It's also fragile, expensive, and non-transferable.

AI cannot build this mental model by osmosis. It cannot attend meetings, overhear conversations, or gradually absorb institutional context over years. It needs explicit connections. It needs structure. When I ask an AI assistant to help me understand why a system behaves a certain way, it can only work with what I provide. If I paste in some code, it can reason about the code. If I add the relevant configuration, it can consider that too. But if the connection between the code, the configuration, the requirement it implements, and the architectural constraints that shaped it exists only in scattered documents and human memory, the AI is working blind. The same applies to more ambitious AI applications. An AI that could autonomously investigate production incidents needs to traverse from alert to metric to log to code to recent change to responsible team. An AI that could suggest architectural improvements needs to understand not just the current structure but the constraints and trade-offs that led to it. An AI that could help with requirements analysis needs to see how requirements connect to implementation and where gaps exist.

None of this is possible when the system doesn't describe itself.

What Self-Description Looks Like

A self-describing system makes its own structure explicit and traversable. Every significant element has a clear definition. Every relationship between elements is captured. The connections are machine-readable, not just human-readable. This isn't a new idea. I've written before about ontologies and knowledge graphs, about how structured knowledge representation enables both human understanding and AI reasoning. I've explored how BPMN can document business processes in ways that serve both purposes. The challenge is applying these concepts to entire software systems.

Here's what the pieces look like:

Requirements as structured data. Not prose documents, but defined artifacts with clear relationships. This requirement depends on that capability. This capability is implemented by these modules. This change affects these requirements. The format matters less than the structure. It could be YAML, JSON, or a domain-specific language. What matters is that the relationships are explicit and queryable.

Architecture as code. Not diagrams that rot, but executable definitions that stay synchronized with reality. Infrastructure as Code is part of this, but architecture is broader. It includes the logical structure, the component boundaries, the integration patterns, the data flows. When someone asks "how does data move from ingestion to reporting," the answer should be derivable from artifacts, not dependent on someone's memory.

Traceable lineage. Every commit links to the work item it addresses. Every deployment records what changed and why. Every configuration change is versioned with context. You can follow a thread from a business requirement through design decisions through implementation through deployment through runtime behavior. The thread is explicit, not reconstructed.

Observable runtime. Logs, metrics, and traces that connect back to the code and configuration that produced them. When something fails, you can traverse from the symptom to the cause to the change that introduced it to the requirement that motivated the change. This observability is designed in, not bolted on.

Documented decisions. Not just what was decided, but why. What alternatives were considered. What constraints applied. What trade-offs were made. This context is essential for AI to provide useful suggestions, because without understanding the constraints, any suggestion might violate assumptions that aren't visible in the code itself.

The Connection to Knowledge Engineering

In an earlier post on knowledge engineering, I argued that the future belongs to organizations that can transform information into structured, contextual knowledge. Self-describing systems are the application of that principle to software itself. The same patterns apply. Taxonomies that classify components and their relationships. Ontologies that define what kinds of things exist and how they can relate. Knowledge graphs that make these relationships traversable. My experiments combining Prolog with language models demonstrated this at a small scale. When policy documents were converted to logical rules with explicit relationships, the AI could reason consistently about them. It could detect conflicts, apply rules to new situations, and explain its reasoning. The structure made the difference. The same principle applies to software systems at large. When the system's structure is explicit and machine-readable, AI can reason about it. When the structure is implicit and scattered, AI is limited to superficial assistance.

Practical Steps

Building a fully self-describing system from scratch is a significant undertaking. But you don't have to do it all at once. Start with the connections that provide the most value. And actually, this is not related to AI and might make your everydays life also easier :)

Link commits to work items religiously. This is the most basic form of traceability, and most teams already do it inconsistently. Make it mandatory. Automate the validation. Build the habit.

Document architectural decisions where they live. I use Architecture Decision Records, simple markdown files stored alongside the code. Each one captures the context, the decision, the alternatives considered, and the consequences. When the codebase evolves, the reasoning evolves with it.

Make configuration explicit and versioned. If a setting affects behavior, it should be in version control with the same rigor as code. No exceptions for "just this one environment variable." The complete configuration should be reconstructible from the repository.

Structure your documentation for traversal. When you write documentation, include explicit links to related code, related requirements, related decisions. Don't assume the reader will find them. Make the connections visible.

Build observability with traceability in mind. When you instrument your code, think about how someone (human or AI) will traverse from an alert to the root cause. Include correlation IDs. Link to relevant code paths. Make the runtime behavior connect back to the static artifacts.

Maintain those two files. As I mentioned in my previous post, CURRENT_WORK.md and WORK_LOG.md have become essential to my workflow. They're a simple form of self-description at the project level. What's happening now. What decisions were made and why. Enough context to resume without archaeology.

The Vision

Imagine a system where you could ask:

  • "What business capabilities depend on this service?"
  • "What would be affected if we changed this data schema?"
  • "Why was this component designed this way, and what constraints still apply?"
  • "What changed between the last stable release and now, and which requirements were involved?"
  • "Where are the gaps between what was specified and what was implemented?"

These questions are answerable today, but only through manual investigation by someone with deep context. In a self-describing system, they become queries. The AI assistant can help answer them because the information is structured and connected, not scattered and implicit. This is the infrastructure that makes AI collaboration meaningful. Not just "help me write this function," but "help me understand and evolve this system."

The Longer Arc

We've covered three ideas in this series.

First, that visual tools and proprietary formats lock AI out of the development process. The no-code trap is real, and it's getting more expensive as AI capabilities grow.

Second, that text is the common language between humans and AI. Everything as Code isn't just a DevOps slogan. It's the foundation for collaboration.

Third, that text alone isn't enough. We need self-describing systems where the structure, relationships, and reasoning are explicit and traversable.

There's more to explore. Cloud consoles have the same problems as no-code tools. The cognitive mismatch between how humans think and how AI processes information runs deeper than tool choices. But the core argument is complete: if we want AI as a genuine collaborator in software development, we need to build systems that AI can read, understand, and reason about.

That means text. That means structure. That means self-description.

The tools are available. The patterns exist. What's needed is the discipline to apply them consistently, even when the visual alternative feels faster in the moment.

The future rewards those who build for it.


This is Post 3 of "The Common Language" series. The core argument is complete, but I may continue with additional posts on cloud consoles as visual builders and the deeper cognitive challenges of human-AI collaboration.

My personal power duo: Linear, connected to Perplextity via MCP

To view or add a comment, sign in

More articles by Hannes Lehmann

Others also viewed

Explore content categories