Dependency Graph Analysis for Agent-Modified Repos
Dependency graphs help agents avoid breaking downstream code they never see.

Architecture drift in AI-generated codebases happens when changes alter dependencies, cross intended boundaries, or weaken contracts in ways that file-level review does not show. Dependency graph analysis exposes those structural changes and the consumers they affect. For agent-modified repositories, the durable approach is to give agents the graph before they patch and enforce architectural constraints against it in CI before they merge.
Why file-level review breaks down when agents modify entire repositories
A field keeps its identifier and type, but its meaning changes from dollars to cents. The patch compiles and passes type-checking, but consumers still read the value as dollars. Those consumers may be in other packages, workspaces, or repositories the agent never saw. Nothing in the local type check exposes the mismatch. The failure appears downstream because the change preserved the field’s shape while breaking its contract.
That gap becomes harder to review when an AI coding agent traverses and modifies an entire repository in a single session. The agent touches dozens of files and rewires call relationships, then hands back a diff organized by file and line. Its unit of work is the session. The reviewer’s interface, however, still separates changes that need to be understood together, leaving the reviewer to reconstruct their combined effect.
The specific failure mode is scope blindness. An agent completes the assigned task, produces a patch that passes its checks, and moves on before the patch causes breakage in a different pipeline. This is not simply a claim that agents write poor code in isolation. A locally correct edit can violate a load-bearing contract when the agent has no model of the larger system.
What a dependency graph actually captures that a diff cannot
A dependency graph represents the codebase as nodes connected by relationships, including imports, call edges, symbol flows, and test bindings. Where a diff records lines added and removed, the graph records what depends on what. That distinction changes the unit of analysis. A changed node can be examined together with its downstream consumers across file boundaries.
Some structural defects exist only between files. A circular dependency among three modules may leave each module looking fine on its own, and a utility imported by dozens of files can become a dangerous bottleneck. Per-file analysis cannot show the whole relationship in either case. The graph makes cycles and concentrations of dependency visible, allowing review to distinguish a small textual edit from a change with broad structural reach.
A useful graph extends beyond module imports. Source-to-test bindings show which tests cover affected code, while architectural layer information makes it possible to check whether an import crosses a forbidden boundary. AgentFlow identifies another layer in agent-framework repositories, including prompt-to-model bindings, tool decorators, memory objects, and handoff declarations. These are dependencies that ordinary call-graph review does not represent. Review now tracks what can reach what and checks that reach against the intended architecture.
The graph does not, by itself, prove that dollars still mean dollars. Its contribution is to expose the consumers whose expectations need examination. That distinction keeps the technique precise. Dependency analysis supplies the structural scope for checking a contract rather than replacing every semantic judgment with an edge.
How graph-based impact analysis changes what an agent does before it commits
Structural information outperforms procedural prompting when an agent needs to avoid regressions. Telling an agent to follow a testing procedure does not tell it which tests its patch could break. A dependency map supplies that missing context. The agent can query the relationships its patch affects, run the tests that cover that code, and fix its work before it submits it.
TDAD, short for Test-Driven Agentic Development, implements this approach through a dependency map between source files and tests. Its evaluation on a software engineering benchmark found a large reduction in regressions. The counterfactual is more revealing than the improvement alone. Adding TDD procedural instructions without targeted test context made regressions worse than no intervention, showing that an instruction to test is not equivalent to knowing where a change can propagate.
The delivery mechanism is deliberately lightweight. TDAD provides a static text file that the agent queries at runtime using grep, with pytest used to run tests. It requires no graph database, MCP server, or API calls. The useful property is not the sophistication of the storage system, but the availability of source-to-test relationships at the point when the agent chooses what to verify.
A second phase of testing used a different model and agent framework and raised both issue-resolution rate and generation rate. That result supports the approach beyond one model configuration without establishing that every repository will behave identically. For agent design, the lesson is to supply the parts of the graph a patch may disturb. The graph then becomes an input to the agent’s work, rather than evidence collected only after a downstream failure.
The graph also traces causation through an agent's own execution trajectory
The same structural technique applies to execution steps as well as source files. In a long-running agent session, the point where an error appears may be far from the point where it originates. A crash at step 50 can follow from an incorrect parameter generated at step 5. Chronological proximity is not the same as causation. Diagnosing the crash requires recovering the dependency between those steps.
Log reduction can destroy precisely that evidence. Truncating a trace may remove the early parameter generation, while supplying the entire trace can bury it among unrelated actions. Both approaches treat the record primarily as a sequence of text. A causal representation instead distinguishes steps that contributed to the failure from steps that merely happened during the same session.
STRACE, short for Structural Trajectory Analysis and Causal Extraction, performs causal localization to filter non-causal steps and identify the root-cause module. It produces compact, high-signal context for optimization rather than passing a monolithic trace to the optimizer. The source graph describes relationships in the system being modified, while the execution graph helps explain how the agent arrived at a faulty outcome.
Both views help in sessions that span dozens of tool calls across many files. One reveals what the resulting code can affect, and the other helps diagnose which earlier action led to a failure. Distant relationships in files or logs become traceable when dependencies are represented explicitly.
Static analysis of agent-framework code requires a graph that understands framework semantics
Agent-framework repositories require more than an import graph because their behavior depends on bindings that ordinary code analysis can miss. Prompts connect to models, tools expose capabilities, memory preserves state, and handoffs transfer control between agents. These relationships define an attack and failure surface. A package inventory may name every component without showing how untrusted text can reach a privileged operation.
AgentFlow introduces the Agent Dependency Graph, or ADG, to represent that layer. It uses typed nodes for agents, prompts, models, capabilities, memory states, and control policies, with typed edges for component dependencies, control flow, and data flow. The graph over-approximates permitted dependencies. It describes what the source code and framework semantics allow, rather than only the path taken during one execution, making it useful for pre-deployment audit.
Pre-deployment audit checks whether untrusted or weakly reviewed text can pass through a prompt, memory state, agent decision, or handoff and reach a privileged capability. AgentFlow applies the ADG to Agent Bill of Materials generation and prompt-to-tool risk detection. The former exposes component-to-binding relationships rather than just component lists, while the latter identifies paths toward operations such as file access, SQL queries, and command execution.
The implementation covers five frameworks, namely OpenAI Agents SDK, LangChain/LangGraph, CrewAI, LlamaIndex, and Semantic Kernel, and was applied to thousands of GitHub projects. Its framework registry needs updates as frameworks change. Over-approximation also produces false positives that need human review. The ADG remains necessary but imperfect evidence, turning an architectural assurance into inspectable nodes and edges.
Encoding architectural constraints as executable graph checks in CI
Research on agent constraint decay finds that correctness degrades as prose architectural requirements accumulate. Requiring Clean Architecture cost approximately 9 points in assertion pass rate, and spelling out the full set of constraints cut assertion pass rates sharply in capable configurations. The agent can forget or trade off requirements it cannot hold in context simultaneously. More instructions are not a durable enforcement mechanism.
An executable architectural fitness function checks the structure that actually landed on disk. If the domain layer imports infrastructure contrary to the declared rule, the check exits non-zero and the build goes red. The gate operates independently of the agent, model, or developer responsible for the patch and of how confidently the change was explained.
ContextCov shows how natural language constraints from agent instruction files can become executable checks. Its Architectural Expert generates code using NetworkX to apply graph algorithms to deterministic constraints, with LLM-assisted judgment for semantic architectural constraints. The checks use the dependency structure to find cycles, layer violations, and boundary crossings. The distinction between deterministic checks and assisted judgment remains important because not every architectural requirement reduces to a fixed graph rule.
AigisCode provides a deterministic pipeline before any AI review stage. It uses source-code parsing, a petgraph dependency graph, and structural detectors for circular dependencies, dead code, hardwired values, and architectural violations. The output is a structured JSON report consumable by agents or CI gates. That separation lets machine-checkable defects reach the gate without depending on an AI reviewer’s interpretation.
In practice, graph-based architectural checks belong in preflight with lint, typecheck, unit tests, and secret scanning, before integration tests, SAST, and dependency scanning. Architectural violations should be reported before merge and block it. Some cases also require escalation and a halt to autonomous merge. These include failing tests whose root cause is unclear, decisions that cross service boundaries, and new dependencies that change graph topology.
What the graph-as-source-of-truth model requires in practice
The graph must be derived from the actual codebase, live in the repository, and version with the code. A diagram kept up to date by hand cannot reliably fill this role. Automatic parsing through a source-code parser, static import analysis, or framework-semantic analysis provides the starting point. Agents must be able to query the resulting graph before they commit, and it must become a first-class CI artifact checked on every PR.
Impact analysis identifies what a proposed edit could disturb, while constraint verification checks the resulting structure for rule violations. Both belong in the same feedback loop. TDAD illustrates the first side, and architectural fitness functions enforce the second, with violations blocking merge in the same way that failing tests do.
The stress-test case described in arXiv:2608.12440 shows the stakes at repository scale. A core architectural invariant was dismantled across 189 files in a codebase of hundreds of thousands of lines, with no test oracle and no human code review. A machine-checked graph constraint would have made that structural violation visible.
For developers, the operational shift is toward defining and maintaining the constraints the graph enforces. This can partially address the “senior tax” of reviewing machine-generated output by freeing some of experienced engineers’ time for system-level design. People still need to use their judgment for false positives, semantic constraints, and decisions that cross service boundaries. But that judgment moves upstream into the rules and relationships that guide agent work. A living map from which to navigate and steer the system replaces a succession of diffs to scroll through as the engineer’s primary interface.
Sources
- TDAD: Test-Driven Agentic Development
- From Noisy Traces to Root Causes: Structural Trajectory Analysis and Causal Extraction for Agent Optimization
- TDAD: Test-Driven Agentic Development - Reducing Code Regressions in AI Coding Agents via Graph-Based Impact Analysis
- AgentFlow: Building Agent Dependency Graphs for Static Analysis of Agent Programs
- Recursive Governance: A Graph-Theoretic Framework for Risk Propagation and Drift Detection in Agentic AI Systems


