Introduction
Large legacy software systems contain enormous amounts of knowledge, but much of it is difficult to discover.
Knowledge exists in source code, databases, configuration, documentation, tickets, logs and development processes. Some of it exists only in the minds of experienced developers. People leave, decisions are forgotten, and the reasoning behind a system gradually becomes harder to recover.
I became interested in this problem while working with large legacy codebases:
How could a developer cross that knowledge void and become productive in an unfamiliar system?
What began as an attempt to build better development tooling eventually led me somewhere rather different: towards knowledge representation and AI.
The Rails IDE
The first version grew out of my experience working on a legacy Rails application.
I initially built a collection of tools, outside office hours, to help me understand the codebase, databases and business domain. What started simply grew into something approaching an IDE, written in C# using WinForms and the .NET Framework. The underlying idea was straightforward:
Bring the information needed to understand a software project closer together.
The application incorporated real-time logging, advanced searching, code maps, scripting, database access, schema exploration, ticket management, notes and other project artefacts.
Logs could be associated with development tickets and subsequently reloaded. Search results, code bookmarks, notes, links and files could also be attached to them.
This was useful during everyday development, but there was another related motivation:
Projects leak information.
People leave. Details are forgotten. Knowledge becomes fragmented across commits, tickets, documentation, source code and conversations. Capturing the context surrounding a development task provided a richer historical record of how a problem had been investigated and solved.
The ambition gradually became one of capturing, relating and surfacing project knowledge.
Process could then help bridge the knowledge void.
Right Problem, Wrong Solution
Project Assist became surprisingly capable. It was my daily driver.
But I was solving the right problem in the wrong way.
I had gradually started building an IDE:
That meant reproducing functionality already provided by enormously sophisticated development environments. It was a lot of work. There are many moving parts in an IDE. I now have a profound respect for IDE developers.
Coming to my senses, I decided to integrate with existing editors and their ecosystem of plugins:
That led to the first important architectural lesson from the project.
Integration was more valuable than replacement. In other words, leverage.
The objective wasn't to build another editor, debugger or development environment. It was to collect, connect and expose information around those tools.
The IDE should remain the IDE.
The tool should become a project knowledge assistant wrapping and augmenting the IDE.
Project Assist
And so, Project Assist came to be, this time written in Delphi:
And I used it to good effect on a much larger legacy system.
This was an ideal environment in which to explore the problem further: more than four million lines of Delphi code, enormous units and methods, state hidden within UI controls, extensive inheritance, hundreds of non-normalized database tables, and considerable domain knowledge residing in the heads of experienced developers.
The challenge was no longer merely finding files or searching source code.
It was understanding a system.
Code was only one part of that system. There were also database structures, configuration, documentation, metadata, and other project artefacts, with relationships between them that were often implicit rather than explicit.
This naturally led to what I thought was the logical next step: more process, more leverage.
So I enriched the assistant with more Delphi functionality, made it a TCP/IP plugin host for external tools and custom C# plugins, and enabled it to communicate with the IDE through a Delphi OTA plugin:
I was throwing the proverbial process-kitchen sink at the problem.
Despite its usefulness, I began to realize that there were better ways of representing information. Everything could be an item with a stereotype, a parent, custom properties, and tags providing basic semantic metadata. An item could both represent a thing and have associations with other things.
Believing I was finally heading in the right direction, I began the next version in earnest, code named Kitae (鍛え). Pronounced key-tah-eh, it means forging, tempering, disciplining, or training, derived from the verb kitaeru (鍛える), meaning to train or forge. It implies improving strength or character through rigorous, repeated effort, similar to tempering steel. This fifth folding of the project was the answer...or so I thought.
From Code to Knowledge
The newer version moved increasingly towards extraction, transformation and normalization.
Delphi ASTs were parsed and normalized. Metadata could be extracted and augmented. Database structures and other project information could be imported into a common model. I used Python scripts and local AI to augment the extracted ASTs and provide summaries of every unit, type and method:
Everything was evolving nicely:
This produced some very useful results. The tooling was working well.
Once information had been transformed into structured data, it became possible to ask questions across the project rather than merely search individual artefacts. I could query code, query metadata, query across artefacts.
I was also able to produce Markdown documentation of units with class diagrams and important notes.
The project was gradually becoming less about development tooling and more about accumulating an explicit representation of knowledge about a software system.
Knowledge had become the centre.
But I now saw the gap between my tooling and Claude for manipulating that knowledge.
Inside Out
Earlier, I had realised that I shouldn't build an IDE around the knowledge.
Now, I began to realize that my current approach would have been perfect a decade ago.
I grasped two truths:
- Knowledge was the real asset
- AI provided the agency to leverage it
Inverting the Architecture
Interestingly, the earlier Rails IDE was leveraging AI back in 2023.
A rudimentary GPT client sat alongside the other development tools:
More recently, Claude had demonstrated just how capable AI had become.
AI has agency. AI becomes the process.
Instead of putting AI inside the knowledge tool, expose the knowledge to AI.
If the system can extract and structure knowledge about a software project, an AI agent can potentially become the semantic interface to that knowledge.
The developer no longer needs to know which database table to search, which service to invoke, which screen contains a particular piece of metadata, or even necessarily how the underlying information has been represented.
That changes the architecture considerably.
Towards AI Agency
The realization that everything could be represented as an item, with associations to other items, naturally led me to graphs. A semantic model can make entities, concepts and relationships explicit. The objective is to construct a representation of the system that can be queried and reasoned over:
Project ETL ⟶ Augmentation ⟶ Knowledge Graph ⟶ AI Agency
Rather than constructing an ever-growing application around these capabilities, the resulting knowledge and services could be exposed to an AI agent through a protocol such as MCP.
Project Assist started as an IDE.
Then it became an assistant.
The next step is for knowledge itself to become the platform.