NarrativeContext

data class NarrativeContext(val graph: ModuleDependencyGraph, val metrics: GraphMetricSet, val summary: GraphSummary, val violations: List<Violation> = emptyList(), val layers: List<LayerSpec> = emptyList(), val teams: Map<String, List<String>> = emptyMap(), val churn: List<ModuleChurn> = emptyList(), val hiddenCoupling: List<CoChange> = emptyList(), val inventory: BuildInventory = BuildInventory.EMPTY, val extensions: ExtensionResult = ExtensionResult.EMPTY)(source)

Everything the narrative finders read, gathered once.

A finder is a pure function of this context, so adding one never changes what the others see and the whole narrative can be regenerated from a graph plus the optional side reports. Fields that come from a task the user may not have run (churn, hidden coupling) default to empty rather than being nullable - a finder that needs them simply produces nothing, which is the honest result.

Parameters

graph

The module dependency graph.

metrics

Structural metrics, computed once by GraphMetrics.compute.

summary

Whole-graph summary (cycles, coupling, god modules).

violations

Rule violations from the current run, if rules are configured.

layers

Declared layers, in declaration order. Empty when none are declared.

teams

Declared team → module glob patterns. Empty when none are declared.

churn

Per-module commit counts from aalekhTemporal. Empty when it has not run.

hiddenCoupling

Strongly co-changing pairs with no declared dependency, from aalekhTemporal.

inventory

How the project is built: plugins, catalogs, toolchains, targets, CODEOWNERS, and declared module metadata. BuildInventory.EMPTY for a graph extracted before this existed.

extensions

Contributions from third-party FindingProviders and ModuleClassifiers. ExtensionResult.EMPTY when no extension jar is on the classpath.

Constructors

Link copied to clipboard
constructor(graph: ModuleDependencyGraph, metrics: GraphMetricSet, summary: GraphSummary, violations: List<Violation> = emptyList(), layers: List<LayerSpec> = emptyList(), teams: Map<String, List<String>> = emptyMap(), churn: List<ModuleChurn> = emptyList(), hiddenCoupling: List<CoChange> = emptyList(), inventory: BuildInventory = BuildInventory.EMPTY, extensions: ExtensionResult = ExtensionResult.EMPTY)

Properties

Link copied to clipboard

Modules sorted by influence, most foundational first.

Link copied to clipboard
Link copied to clipboard

Commit counts keyed by module, empty when aalekhTemporal has not run.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

True when any ownership source is configured at all - otherwise ownership findings stay quiet.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

True when the project is large enough for a claim about proportions to mean anything.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
fun layerOf(path: String): String?

The layer a module belongs to, or null when nothing assigns one.

Link copied to clipboard
fun purposeOf(path: String): String?

What a module is for, when anyone has said.

Link copied to clipboard
fun teamOf(path: String): String?

The team owning a module, or null when nothing claims it.