| name | dak-project-unit-topology |
| description | Inspect Delphi project unit topology with DelphiAIKit `deps`: resolved and unresolved units, project vs external edges, SCCs, cycle hotspots, and focused unit views. Use when Codex needs to answer what depends on what, why a unit is present, whether project-unit cycles exist, where to start reducing cycle debt, which `uses` edge is the best first candidate to cut, or when a Delphi `.dproj` needs dependency-topology diagnosis. |
Delphi Project Unit Topology
Use DelphiAIKit.exe deps for project-level dependency shape and cycle triage.
If DAK_EXE is missing, use dak-build setup.
Preflight:
test -x "$DAK_EXE" || { echo "DAK_EXE not executable"; exit 1; }
Route The Request
Use this routing before running commands:
| User intent | Use | Read first |
|---|
| "What depends on what?" / "Why is this unit here?" | deps --format json | summary, nodes, edges |
| "Do we have cycles?" | deps --format json | cycleComponents |
| "Where do we start fixing cycle debt?" | deps --format json | cycleComponents, unitHotspots, edgeHotspots |
| "Show one unit in context" | deps --format text --unit "<UnitName>" | focused text report |
| "Give me a short ranked list" | deps --format text --top <N> | hotspot text sections |
| "Who reads or writes this global?" | switch skill | dak-global-vars |
| "Will this build succeed?" | switch skill | dak-build |
Start with JSON unless the user only wants a quick human-readable follow-up.
Command Patterns
Full graph:
"$DAK_EXE" deps --project "<path-to-project.dproj>" --format json
Focused unit:
"$DAK_EXE" deps --project "<path-to-project.dproj>" --format text --unit "ProblemUnit"
Compact hotspot summary:
"$DAK_EXE" deps --project "<path-to-project.dproj>" --format text --top 10
Rules:
--top affects text hotspot sections only. Default is 20; 0 means unlimited.
- If
--output is omitted, DAK still writes an artifact under .dak/<ProjectName>/deps/.
- Use
--output - to redirect output to stdout instead of a file; useful when piping into a subsequent tool.
- Read
project.contextMode and project.contextNote before making strong claims.
What The JSON Means
Treat JSON as the primary interface. The important fields are:
project.contextMode: full or degraded
summary.*: node, edge, unresolved, and parser-problem counts
nodes[*].isProjectUnit: project-owned vs external resolved unit
nodes[*].resolution: resolved, unresolved, or parserProblem
nodes[*].unitCycleScore: SCC-internal degree; 0 means not in a detected cycle
nodes[*].sccId: SCC membership; null means acyclic
edges[*].edgeKind: project, contains, interface, or implementation
edges[*].isCycleEdge: true if both endpoints are in the same SCC
unresolvedUnits[*]: unresolved referenced unit names
parserProblems[*]: units whose parsing failed
cycleComponents[*]: structured SCC records; prefer these over cycles
cycleComponents[*].representativeCycle: real traversal path, not a synthetic alphabetical join
unitHotspots[*]: ranked hub candidates inside SCCs
edgeHotspots[*]: ranked edge-cut candidates inside SCCs
cycles[*]: compatibility array only; do not use as the primary analysis surface
Minimal shape:
{
"project": { "contextMode": "full" },
"summary": { "nodeCount": 4, "edgeCount": 4 },
"nodes": [
{ "name": "Main", "resolution": "resolved", "unitCycleScore": 4, "sccId": 1 }
],
"edges": [
{ "from": "Main", "to": "Shared", "edgeKind": "interface", "isCycleEdge"
Interpretation Rules
Use these rules consistently:
- If
contextMode=degraded, lower confidence. Missing search-path edges can distort SCCs and hotspot scores.
- If
cycleComponents is empty, report that the resolved project graph is acyclic and stop the hotspot analysis.
unitCycleScore is intra-SCC degree, not a simple-cycle count. Do not say "appears in N cycles."
edgeHotspotRank is the sum of endpoint scores. It is a heuristic for leverage, not proof that one cut breaks the SCC.
- Prefer
implementation edges when ranks tie. implementation edges are cheaper to break because the dependency is internal to the unit — only that unit's code needs changing. interface edges expose types or routines in the unit's public API, so breaking them ripples into all callers and often requires moving a shared type into a new neutral unit.
- Treat
refactorabilityHint=easier as a first candidate, not a guarantee of low effort.
- Do not claim the hotspot list is exhaustive when unresolved units or parser problems are nearby.
- Re-run
deps after a refactoring. Use the new SCC and hotspot output as proof of improvement.
Use deps to answer:
- what depends on what
- why a unit is present
- whether a dependency is internal or external
- whether project-unit cycles exist
- where to start reducing cycle debt
- which unit is the main hub in a cycle cluster
- which
uses edge is the best first candidate to cut
Do not use deps alone to answer:
- who reads or writes a variable
- which routine calls a method
- how a symbol binds
- whether the project builds successfully
Operating Workflow
For topology questions:
- Run
deps --format json.
- Read
project.contextMode, summary, nodes, edges, unresolvedUnits, parserProblems.
- Quote exact unit names and edge kinds.
- If the user asks about one unit, rerun with
--format text --unit.
For cycle-remediation questions:
- Run
deps --format json.
- Read
cycleComponents first.
- If there are no SCCs, report that there is no detected cycle debt in resolved project units.
- Read
unitHotspots to identify the most connected hubs.
- Read
edgeHotspots to identify likely first-cut edges.
- Prefer
implementation edges over equal-rank interface edges.
- Recommend one concrete first cut and explain why it is a candidate.
- State that one cut may reduce hub connectivity without dissolving the whole SCC.
Reporting Pattern
For topology findings, report:
- context quality:
full or degraded
- target unit or subsystem
- relevant edges, unresolved units, parser problems, or SCC membership
- what
deps does not prove
For cycle-hotspot findings, report:
- number of SCCs and the largest component
- top unit hubs with
unitCycleScore
- top edge candidates with
edgeKind, edgeHotspotRank, and refactorabilityHint
- one concrete first-cut recommendation
- a caveat that the SCC may survive and should be re-checked with another
deps run
Example hotspot summary:
The graph has 2 cycle components. The largest SCC has 11 units and 23 internal edges.
`DataModule` is the main hub (`unitCycleScore=12`), followed by `GlobalVars` (`9`).
The best first candidate is `DataModule -> GlobalVars` because it is an
`implementation` edge with the highest reported rank. That makes it a cheaper first
cut than an equal-rank `interface` dependency, but it is still only a candidate. Re-run
`deps` after the change to confirm whether the SCC shrank or disappeared.