# SemDAG: A Dependency Graph for Knowledge https://workspace.socra.com/blog/engineering/the-semdag Published: 2026-09-03 Updated: 2026-09-04 Author: Mike Morton I've been writing code for almost ten years, and I would say the hardest problem I've had with software development has been getting other people and their agents to understand our systems the way I do. How everything connects together, how we build things, why we do things a particular way. A lot of that organizational know-how was locked in my head. When we started Socra, I was the only one who could write any code. And I loved it. I loved being able to think up something that I wanted to show on a screen and then make that a reality. You write something in a computer, and then you can render something to somebody, and it might make their life a little better. That's such a cool thing that you can do. So over time, we built quite a lot. We had all of this infrastructure, all of these services, all of these different things that connected together. And when my co-founder Ed started getting into software development, she was coming in as a junior developer. There was a lot she had to learn before she could write code in a way that was conformant to how our systems worked. In the beginning, GitHub Copilot was essentially a nice autocomplete tool. You could start typing, pause, and it would complete the rest of a function. That was a nice productivity boost for me. But you still had to know enough to get to the point where you were accepting the completion, so it didn't help her very much. Then we moved on to Cursor, and when agent mode came along, that was the point where she could start contributing quite a lot more code. As the agents got smarter, they could work for longer, and the quality got better. Claude Code was a big step for us. But it still lacked all of the organizational knowledge, all of the stuff that was locked in my head. At some point, the volume of code she could produce far exceeded my ability to review it. And I was working on our other top priorities, so every time I needed to stop and review something, it came at the expense of the work I was doing. I had become the bottleneck. What made that difficult was that I could look at a change and immediately see, "Man, we don't do it this way. This is going to have these problems." And then I would look a little deeper, pull back another layer of the onion, and it would get worse. You spend years building something carefully, and then you watch it getting worse and worse. It was really heartbreaking. We tried several things. We split our large monorepo into smaller repositories by domain, which helped us manage the work. We put instructions into `AGENTS.md`. And those instructions helped with the thing that was right there in that file. But that thing often required other things to be understood first, and those things had their own prerequisites. So you could teach the agent how to do this one thing, but it still wouldn't understand that thing in context. I was still the person who had to explain how all of it connected together. And as we got more repositories and more agents writing code, that problem just kept multiplying. We experimented with a lot of different prototypes, and the solution we arrived at, I think, is interesting because it rhymes with how code is actually structured and how code is modularized and abstracted. Let's say you're building a TypeScript library, or a library in whatever language you like to use. That library probably depends on other packages, and those packages have dependencies on other packages. When you use the library, the things it depends on have to be available for it to work. You already have this structure for expressing what depends on what. You can do the same thing with knowledge. You can say, "Here's how we do this, but in order for you to understand it, you need to understand these other things first." And each of those things can have its own dependencies. So you can break the knowledge into little discrete pieces and connect them together, just like you would modularize code. That's what we built with Cortex. The technology underneath it is what we call a SemDAG, which stands for Semantic Directed Acyclic Graph. It's a fancy word, but you don't have to remember that. All you have to remember is that there are different pieces of knowledge, and they're connected together so you can learn one thing with the right prerequisite knowledge. Each piece is what we call a Module. When I talk about a dependency, what I'm really talking about is this: in order to understand A, I need to understand B first. So A depends on B. And if B depends on C and D, then I need to teach you C and D, then B, and then A. There has to be an order in which you can learn those things, with the foundations first. And then you can point your agent at a Module and say, "Hey, I want you to go learn this." We call that a flash. The agent makes a call to Cortex through the CLI, MCP, or API. Cortex walks through the dependencies you've specified, gets the context from each of those Modules, and assembles it into a single topologically ordered bundle. All that means is that the prerequisite knowledge comes before the knowledge that depends on it. If two parts of the graph need the same foundation, that foundation gets included once. By the time the agent reaches the Module you asked for, the prerequisite knowledge is already there in its context window. It's in-context learning, from the foundations up, before it starts working on the thing. I think about it kind of like Neo in The Matrix when he downloads kung fu into his brain. You can tell the agent, "Go learn this," and give it the specific knowledge for the work it's about to do. For example, we have our own database layer and our own ORM. There are particular ways we define models, work with relationships, and handle transactions. An agent needs to know how our ORM works before it starts writing code that uses it. My co-founder was building a service, and before we had Cortex, her agent didn't have that knowledge. The way it handled the database was a mess. So I said, "Just use our database Module. Put that as a dependency of the service you're building, and then have your agent flash your Module." And then it went back and refactored the code to follow the way we do databases. All I had to say was, "Use this Module." I didn't have to say, "Here's how we use databases. Here's the whole ORM. Here's this and that." I just had to write that once, and then everything downstream benefits from it. UI is another example. We have our own shared components, and we want agents to use those components when they build our interfaces. So the knowledge about how those components work, how they should behave, and how to use them can live upstream and be consumed by the products that need it. We've found that very useful for getting our agents to build things in a way that adheres to our principles. And this goes beyond code. One of my favorite Modules to flash is called `workspace-customer`. It's our customer profile for Workspace. That Module depends on how we define Workspace, which depends on how we define an Account, which depends on our definition of identity. Those foundations give the customer profile its context. I can simply tell an agent: ```sh socra cortex flash workspace-customer ``` And then when I ask whether the messaging on a landing page makes sense for our customer, the agent has that chain of knowledge available. It knows who we're building for and how that customer fits into what we're building. That's really valuable when you're asking an agent to help you make decisions. It's also why the knowledge lives outside of any particular codebase. Our customer profile is useful to somebody building a landing page, but it's useful to somebody thinking about the product or working on marketing too. They should be able to use that knowledge wherever they're doing their work. So the way I think about this is that you're programming at a higher level of intent. I call it your semantic intent. You're defining how your system should work and what depends on what, and then the agents reconcile the code to those specifications. It's kind of like compiling. You can compile code into a binary, and here you're giving an agent semantic instructions that it uses to produce code. The agent still has to inspect the implementation and check its work. The Modules give it the knowledge to understand what it's trying to build and what good looks like in your system. When that intent changes, you change the Module, and then the work is to bring the implementation into agreement with it. In our process, an agent can propose a change, and the owner decides what becomes part of that knowledge. Cortex also has Issues, which are how we coordinate that work. A Module describes how something should be, and an Issue describes work needed to get it there. An Issue can depend on another Issue when that work needs to finish first. So the knowledge has an order for understanding it, and the work has an order for doing it. What I like about working this way is that we can spend more time talking about the concepts and what we want the requirements to look like. The knowledge stays one layer upstream, where we can use it across different repositories and different agents. There's a concept in programming called DRY, which means don't repeat yourself. If you're copying and pasting the same function into a bunch of places, that's usually a good signal that you need an abstraction. The way we were using agents, we were constantly repeating ourselves. And that makes absolutely no sense from a programming perspective. We were explaining the same decisions and the same reasons for doing things over and over. With a SemDAG, you can write a piece of context once and make it a dependency of other context. It can be several layers down in the graph, and the agent still gets it when it flashes something that depends on it. You get to reuse the knowledge without having to copy it into every place that needs it, which is probably one of the coolest things about the whole system for me. As the models get smarter, I think that specific knowledge becomes more valuable. It's the hard-won knowledge that your senior engineer has, or your technical expert has, that lets them look at something and understand why it's going to work or why it's going to have problems in your system. We want that knowledge available to the people and agents doing the work. Since we started using Cortex, I've found myself banging my head on the wall a lot less. When I look at the code, it's adhering to our principles much better. And I feel a lot better about what we're building. With the right processes, Cortex included, the agents can understand what good looks like before they ever touch a file. # Introducing Cortex https://workspace.socra.com/blog/product/introducing-cortex Published: 2026-09-01 Updated: 2026-09-03 Author: Mike Morton We released Cortex on September 1, 2026. Cortex lets you share context across your AI agents, giving each agent the right knowledge before it acts. You write down how your system should work and why, connect that knowledge by dependency, and let an agent retrieve the part its task needs. ## The reasons behind your system An agent can read a function and understand what it does. The reason you chose that behavior can be much harder to recover. A constraint may come from a customer promise or a failure you investigated months ago. The code shows the decision. It may leave out the reason that still makes the decision correct. As agents take on more work, you have to carry those reasons into more conversations. Missing context can produce AI slop: competent-looking generic work that loses the specific judgment behind your system. Reviewing the patch helps, but by then the agent has already acted. We built Cortex so you can give it that knowledge at the start. ## Write the rule where the next agent can find it A **Module** is a named, versioned specification of how one part of a system should work and why. It gives a piece of knowledge a stable name and an owner. You can change the implementation while keeping the requirement clear. For example, imagine a team building an AI research assistant. Its answers need a rule for handling missing source material. The following is a fictional Module, included to show what a small piece of useful knowledge could look like. ### Example Module: answer-policy - Every factual answer cites the source passages used to produce it. - When the sources do not support an answer, say what evidence is missing. Readers need to be able to check the claim. Depends on: retrieval, citations. The reason belongs beside the rule. An agent asked to reduce latency then has enough context to recognize that dropping source checks would change the product's promise. This example describes a decision the rule is meant to inform; it is not a measured result from a customer run. ## Bring the dependencies with it Knowledge often needs other knowledge to make sense. An answer policy may depend on rules for retrieving documents. Those rules may depend on who owns each document and who can read it. Cortex connects Modules through declared dependencies. We call this structure a **Semantic Directed Acyclic Graph (SemDAG)**. It connects Modules by dependency. An agent **flashes** a Module to receive it with its complete dependency tree, foundations first. Each Module appears once, even when several paths lead to it. With a Module named `answer-policy` in your Account, the call is: ```bash socra cortex flash answer-policy ``` The agent receives the knowledge the team declared necessary for that subject. It still needs to inspect the repository and verify current evidence before making a change. A flash supplies context; the agent's host and your team's approval rules govern how it acts on that context. ## Keep the work connected to the knowledge An **Issue** records bounded work and names its owning Module. An agent can read the Issue, flash that Module, and compare the requested change with the rules that govern it. This gives the next task a clear starting point. It also keeps two different questions explicit: what should the system do, and what work is needed to bring it there? Module dependencies describe what must be understood. Issue dependencies describe what must finish first. As the team learns, the knowledge can change. Cortex preserves immutable Module revisions so earlier rules and their authors remain available. Agents should propose durable knowledge changes under the team's approval rule. The person responsible for the rule decides what to keep. ## Use Cortex with your agent You can work with Cortex through its web app, CLI, or hosted MCP server. The [integration guides](/docs/cortex/integrations) explain how to connect the agent you use. Start with one subject you already find yourself explaining, and write the reason another person would need to preserve it. Then ask your agent to find and flash that Module when the work needs it. A successful flash is the first useful checkpoint: the knowledge has reached the agent in the conversation where it can use it. [Open Cortex](https://cortex.socra.com) to work with your team's Modules, or read [how SemDAG assembles context](/blog/engineering/the-semdag) for the technical details.