The Shadow Org Chart: Reconstructing How a Company Actually Works with Machine Learning
A technical guide to inferring hierarchy, structural roles, bottlenecks, organizational fragility, and coordination failure from interaction exhaust — with graph theory, temporal models, topology, and runnable Python

Every organization has at least two structures.
The first is the one everybody can see. It lives in Workday, PowerPoint, the annual report, and the boxes-and-lines diagram shown during reorganizations. It tells us who formally reports to whom, which functions own which responsibilities, and where authority is supposed to reside.
The second organization is harder to see.
It is a dense, weighted, time-varying system of conversations, meetings, approvals, handoffs, code reviews, document edits, escalations, ticket transitions, and dependencies. Nobody designed it explicitly. Nobody approved it as an operating model. Yet it is the structure through which much of the company’s actual work moves.
The formal organization is a tree.
The operational organization is closer to a temporal, multiplex network.
And increasingly, that second organization is measurable.
Not perfectly. Not without confounding. Certainly not without serious ethical constraints. But communication metadata, calendars, workflow transitions, software dependencies, incident records, document collaboration, and other forms of organizational exhaust contain enough relational information to reconstruct aspects of how a company actually coordinates.
That makes a different class of organizational analysis possible.
Instead of asking only how the organization was designed, we can ask what structure it has actually converged to. We can estimate whether formal authority and behavioral authority agree. We can identify teams connected by a single fragile bridge. We can distinguish hubs from brokers and bottlenecks. We can estimate whether communication is mostly responding to external work or recursively generating more communication. We can compare the organizational network with the architecture of the systems it builds.
Most importantly, we can measure the gap between the company on the org chart and the company that appears in the interaction data.
This article develops a technical framework for doing that.
The pipeline combines several ideas from network science, information theory, temporal point processes, spectral graph theory, optimal transport, and causal inference:
- Salience-Weighted Interaction Networks, using group-size discounting and positive pointwise mutual information to separate meaningful relationships from raw communication volume.
- Latency-Deference HodgeRank, which treats conditioned response-time asymmetry as a candidate signal of latent authority and decomposes it into globally consistent hierarchy, local cycles, and longer-range circulation.
- The Role–Community Bimatrix, which separates the question of where someone sits in the interaction network from what structural function their position performs.
- Keystone Fragility, which uses effective resistance to identify positions whose removal disproportionately damages network connectivity.
- Organizational Criticality, using a multivariate Hawkes-process approximation to distinguish baseline activity from recursively triggered communication.
- Topological Genotype, using Gromov–Wasserstein comparison to ask which idealized organizational architecture the observed company most resembles.
- Conway Alignment, which tests whether the structure of human coordination matches the dependency structure of the systems those humans operate.
The mathematics is useful. The code is useful. But the most important point comes before either of them:
This is not employee scoring.
It is sociotechnical measurement.
If the system becomes a mechanism for ranking individual workers, the measurement problem has already been corrupted.

1. The Formal Object: An Organization as a Temporal Multiplex Hypergraph
The natural representation of organizational interaction is not a simple graph.
Suppose the organization contains N actors, and activity occurs across email, chat, meetings, code review, ticketing systems, documents, incident platforms, and other channels. A useful starting point is a temporal, directed, multiplex hypergraph:
H = (V, E, L, T) V = set of actors L = interaction layers T = observation window E = set of interaction events
An event can be represented as:
e = (S_e, r_e, l_e, t_e, m_e) S_e = participant set r_e = originator, when one exists l_e = interaction layer t_e = timestamp m_e = metadata
The metadata might include duration, thread identifier, reply-to pointer, ticket state, meeting type, or other non-content attributes.
The distinction between a graph and a hypergraph matters immediately.
A meeting with 40 participants is not equivalent to 780 independent interpersonal relationships.
Yet that is exactly what happens if the meeting is naively projected into an ordinary graph by creating an equal edge between every pair of attendees.
The network becomes dense largely because large meetings exist.
The analyst then discovers that everyone is “highly connected.”
What has actually been discovered is a projection artifact.
The first requirement of a useful organizational-network pipeline is therefore to preserve higher-order interaction structure as long as practical and, when projecting to pairwise relationships, explicitly discount the effect of group size.
2. Salience-Weighted Interaction Networks
2.1 Large meetings should not create hundreds of strong relationships
For an event containing k participants, I use the collaboration weighting associated with Newman’s treatment of scientific collaboration networks [1]:
pair contribution = 1 / (k - 1)
for each pair of participants in the event.
This normalization is participant-centered.
Each participant accumulates total incident interaction mass of approximately one from the event regardless of its size. A one-to-one meeting therefore represents a strong pairwise interaction, while each pair inside a 40-person meeting receives only 1/39 of a unit.
Large meetings still contribute more total network activity because more people attended them. They simply stop pretending that every attendee formed an equally strong relationship with every other attendee.
This is an important distinction.
An all-hands is evidence that 500 people occupied the same communication event.
It is not evidence that 124,750 meaningful dyadic relationships were created.
2.2 Organizational structure decays
Organizations are not static networks.
The employee who coordinated two teams eighteen months ago may no longer occupy that role. A product launch can temporarily create dense cross-functional interaction. A reorganization may formally happen on Monday while the old communication pathways persist for months.
Recent interaction should therefore usually matter more than distant interaction.
One simple weighting is exponential decay:
decay(e) = exp(-(T_now - t_e) / lambda)
If h is the desired half-life:
lambda = h / ln(2)
There is no universal organizational half-life. A rapidly changing product organization may require a much shorter window than a stable manufacturing operation.
I would therefore treat the half-life as a parameter to validate rather than declaring six weeks or ten weeks intrinsically correct.
The important principle is that the inferred organization should have a temporal definition.
“The organizational network” is meaningless without answering:
Over what period?
2.3 Preserve the multiplex structure before collapsing it
Let:
C[i,j,l]
represent the temporally weighted interaction mass between actors i and j in layer l.
This gives us an actual interaction tensor across actors and communication layers.
Only later do we collapse across channels:
C_ij = sum_l gamma_l * C[i,j,l]
where gamma_l is a layer weight.
Those weights need not all be equal.
A direct code-review assignment may contain different structural information than co-attendance at a recurring 200-person meeting. An incident escalation may carry a different signal than passive membership in a Slack channel.
Ideally, layer weights are learned or validated against an outcome of interest rather than selected because they “feel right.”
2.4 The loud-person problem
Raw contact volume creates another distortion.
Consider an executive assistant who schedules hundreds of meetings, a manager with 18 direct reports, a support lead who participates in every escalation, or a bot that posts into dozens of channels.
Raw network centrality will frequently place these actors near the center of the company.
But high volume and high structural salience are not the same thing.
To distinguish them, treat the interaction matrix as a co-occurrence distribution.
Define:
p_ij = C_ij / sum_ab C_ab p_i = sum_j C_ij / sum_ab C_ab
Then calculate pointwise mutual information:
PMI(i,j) = log( p_ij / (p_i * p_j) )
and positive PMI:
PPMI(i,j) = max(0, PMI(i,j))
The intuition is straightforward.
PMI asks whether two actors interact more often than we would expect given how active each actor is overall.
Suppose two extremely active executives exchange 40 interactions. Forty sounds substantial. But if their marginal activity predicts 300 interactions, the relationship is actually weaker than expected.
Conversely, two specialists who rarely interact with anyone else may have only 15 interactions with each other, yet those 15 interactions may be extraordinarily concentrated relative to their baselines.
PPMI can overvalue rare events, so I damp it by observed volume:
w_ij = PPMI(i,j) * log(1 + C_ij)
The resulting weights emphasize relationships that are both statistically salient and supported by repeated interaction.
I call the layer-preserving version the Salience-Weighted Interaction Tensor and its collapsed graph the Salience-Weighted Interaction Network, or SWIN.
The distinction is worth making because the tensor contains information that disappears once layers are aggregated.
2.5 Extract the backbone rather than thresholding arbitrarily
Even after salience weighting, organizational networks can remain extremely dense.
A global threshold such as “remove all edges below 0.2” is usually a poor solution because it disproportionately removes meaningful relationships around low-volume nodes.
Instead, use a multiscale backbone method such as the disparity filter developed by Serrano, Boguñá, and Vespignani [2].
For node i:
x_ij = w_ij / sum_j w_ij
Under the disparity-filter null model:
alpha_ij = (1 - x_ij)^(k_i - 1)
where k_i is the degree of node i.
An edge can be retained when it is unexpectedly important to at least one endpoint.
The advantage is local adaptation.
A weight that is insignificant around a highly connected executive may be structurally important around a specialist with four relationships.
2.6 Python implementation
import numpy as np
import networkx as nx
def build_swin(
events,
n_nodes,
t_now,
half_life_days=45.0,
layer_weights=None
):
"""
Build a temporally decayed, group-size discounted,
salience-weighted organizational network.
events:
list of dicts with:
participants : list[int]
layer : str
t : float, measured in days
Returns:
W : symmetric salience-weighted adjacency matrix
"""
lam = half_life_days / np.log(2.0)
layer_weights = layer_weights or {}
C = np.zeros((n_nodes, n_nodes), dtype=float)
for e in events:
participants = sorted(set(e["participants"]))
k = len(participants)
if k < 2:
continue
decay = np.exp(-(t_now - e["t"]) / lam)
layer_weight = layer_weights.get(e["layer"], 1.0)
pair_mass = layer_weight * decay / (k - 1)
for a in range(k):
for b in range(a + 1, k):
i = participants[a]
j = participants[b]
C[i, j] += pair_mass
C[j, i] += pair_mass
total = C.sum()
if total <= 0:
return C
p_ij = C / total
p_i = p_ij.sum(axis=1, keepdims=True)
expected = p_i @ p_i.T
with np.errstate(divide="ignore", invalid="ignore"):
ratio = np.divide(
p_ij,
expected,
out=np.ones_like(p_ij),
where=expected > 0
)
pmi = np.log(ratio)
ppmi = np.maximum(
0.0,
np.nan_to_num(pmi, nan=0.0, posinf=0.0, neginf=0.0)
)
W = ppmi * np.log1p(C)
np.fill_diagonal(W, 0.0)
return (W + W.T) / 2.0
def disparity_backbone(W, alpha=0.05):
"""
Multiscale disparity-filter backbone.
Uses the union rule across edge endpoints.
"""
strength = W.sum(axis=1)
degree = (W > 0).sum(axis=1)
keep = np.zeros_like(W, dtype=bool)
for i in range(W.shape[0]):
if degree[i] < 2 or strength[i] <= 0:
keep[i, W[i] > 0] = True
continue
x = W[i] / strength[i]
p_value = (1.0 - x) ** (degree[i] - 1)
keep[i, (W[i] > 0) & (p_value < alpha)] = True
keep = keep | keep.T
return W * keepAt this point we have something much more useful than a communication-volume graph.
We have a statistically filtered estimate of relational salience.
Now we can begin asking harder questions.
3. Latency-Deference HodgeRank: Can Interaction Timing Reveal Effective Authority?
Formal hierarchy is stored in the HR system.
Effective authority is not.
Teams contain dotted-line relationships, technical leaders without managerial titles, staff engineers who influence several functions, project leaders with temporary authority, executives bypassed by operational teams, and managers whose formal authority is much greater than their practical authority.
One behavioral signal worth testing is asymmetric response latency.
The premise is not that slow responses equal power.
That would be absurdly simplistic.
The hypothesis is narrower: after accounting for obvious alternative explanations, persistent asymmetry in how two actors respond to one another may contain information about dependence, urgency, authority, or deference.
Let:
tau(i -> j)
represent the conditioned response time of actor i to actor j.
Define the pairwise score:
Y_ij = log( tau(i -> j) / tau(j -> i) )
By construction:
Y_ji = -Y_ij
If Y_ij is positive, actor i tends to keep j waiting longer than j keeps i waiting.
But raw latency should never be used.
Someone may respond slowly because they are overloaded, live in another time zone, work different hours, receive more messages, use email less often, or occupy a role where immediate response is not expected.
Before calculating pairwise deference, condition out these effects.
A practical model might include:
log latency
~ sender effect
+ receiver effect
+ channel
+ working-hour overlap
+ timezone difference
+ thread position
+ message-size proxy
+ weekday
+ sender workload
+ receiver workloadThe relational signal should come from residual sender-receiver asymmetry after these terms have been modeled.
Even then, I would call it a latent-authority candidate signal rather than “measured authority.”
Validation comes later.
3.1 Recovering a global ordering
Suppose Y contains pairwise asymmetric scores.
We want a scalar potential s such that:
Y_ij approximately equals s_i - s_j
We can recover s through weighted least squares:
minimize over s: sum_(i<j) w_ij * ((s_i - s_j) - Y_ij)^2
This is the HodgeRank problem developed by Jiang, Lim, Yao, and Ye [3].
The normal equations are related to the weighted graph Laplacian:
L s = div(Y)
The result is a latent ordering that best explains the observed pairwise asymmetries.
But the residual is more interesting than the ranking.
3.2 Authority can be inconsistent
Pairwise organizational relationships do not necessarily admit a single global hierarchy.
Imagine three actors:
A responds quickly to B.
B responds quickly to C.
C responds quickly to A.
There is no scalar ranking capable of satisfying all three relationships simultaneously.
This is where combinatorial Hodge theory becomes useful.
An antisymmetric edge flow can be decomposed into components associated with a global gradient, local cyclic inconsistency, and longer-range cycle structure.
Conceptually:
observed flow
=
consistent gradient
+
local cyclic flow
+
remaining global circulationFor organizational interpretation:
The gradient component represents the portion of the relational signal explainable by one globally consistent ordering.
The local cyclic component captures triangular contradictions: A defers to B, B to C, and C back to A.
The remaining circulation captures cycles not explained by those local triangles.
That decomposition suggests a useful statistic:
Hierarchy Coherence Index
=
gradient energy / total flow energyBut this statistic should not be assigned universal thresholds.
There is no empirical reason to assume that an HCI of 0.70 has the same organizational meaning in a 40-person startup, a matrixed pharmaceutical company, and a 15,000-person engineering organization.
Treat it as a calibrated measurement.
Bootstrap interaction events.
Estimate a confidence interval.
Compare it with known reporting relationships where those reporting relationships are meaningful.
Track it longitudinally within the same organization.
Most importantly, examine where cyclic inconsistency concentrates.
A company-wide HCI can tell you that ambiguity exists.
The triangles tell you where.

3.3 Python implementation
import numpy as np
import networkx as nx
from scipy import sparse
from scipy.sparse.linalg import lsqr
def hodge_decompose(W, Y, tri_cap=200000):
"""
Approximate Hodge decomposition over the clique complex
induced by the weighted backbone.
W : symmetric nonnegative edge weights
Y : antisymmetric pairwise relational scores
If tri_cap truncates triangle enumeration, the returned
curl/harmonic split should be interpreted as approximate.
"""
n = W.shape[0]
iu = np.triu_indices(n, 1)
mask = W[iu] > 0
ei = iu[0][mask]
ej = iu[1][mask]
m = len(ei)
w = W[ei, ej]
y = Y[ei, ej]
sw = np.sqrt(w)
# Edge-node incidence matrix
D = sparse.csr_matrix(
(
np.concatenate([np.ones(m), -np.ones(m)]),
(
np.concatenate([np.arange(m), np.arange(m)]),
np.concatenate([ei, ej])
)
),
shape=(m, n)
)
# Weighted least-squares gradient projection
D_weighted = sparse.diags(sw) @ D
s = lsqr(
D_weighted,
sw * y,
atol=1e-10,
btol=1e-10
)[0]
s -= s.mean()
grad = D @ s
residual = y - grad
# Enumerate triangles
edge_id = {
(a, b): idx
for idx, (a, b) in enumerate(zip(ei, ej))
}
G = nx.from_numpy_array(W)
triangles = []
for a in range(n):
neighbors = [x for x in G.neighbors(a) if x > a]
for bi in range(len(neighbors)):
for ci in range(bi + 1, len(neighbors)):
b = neighbors[bi]
c = neighbors[ci]
if G.has_edge(b, c):
triangles.append((a, b, c))
if len(triangles) >= tri_cap:
break
if len(triangles) >= tri_cap:
break
if len(triangles) >= tri_cap:
break
rows = []
cols = []
vals = []
for t, (a, b, c) in enumerate(triangles):
for u, v, sign in [
(a, b, 1),
(b, c, 1),
(a, c, -1)
]:
rows.append(t)
cols.append(edge_id[(u, v)])
vals.append(sign)
if triangles:
C = sparse.csr_matrix(
(vals, (rows, cols)),
shape=(len(triangles), m)
)
C_scaled = C @ sparse.diags(1.0 / sw)
z = lsqr(
C_scaled.T,
sw * residual,
atol=1e-10,
btol=1e-10
)[0]
curl_scaled = C_scaled.T @ z
curl = curl_scaled / sw
else:
curl = np.zeros(m)
harmonic = residual - curl
def energy(v):
return float(np.sum(w * v ** 2))
total = energy(y) + 1e-12
triangle_curl = np.array([
abs(Y[a, b] + Y[b, c] + Y[c, a])
for a, b, c in triangles
])
return {
"latent_potential": s,
"hierarchy_coherence": energy(grad) / total,
"local_cycle_fraction": energy(curl) / total,
"remaining_cycle_fraction": energy(harmonic) / total,
"triangles": triangles,
"triangle_curl": triangle_curl
}If every relevant triangle is included, the decomposition has the clean Hodge interpretation.
If triangle enumeration is capped for computational reasons, some unmodeled local cyclic structure can leak into the residual. In that case the final component should be interpreted conservatively as unresolved circulation rather than perfectly measured harmonic flow.
The method is still useful.
The important question is not whether a company has a hierarchy score of 0.63.
The important question is whether inconsistent authority is concentrated around the same teams that experience duplicated approvals, escalation loops, or unusually long decision latency.
That is a testable organizational hypothesis.
4. The Role–Community Bimatrix: Where You Work Is Not What You Do
Community detection answers an important question:
Who interacts disproportionately with whom?
It does not answer another important question:
What structural function does a node perform?
Those are different dimensions.
A technical lead in payments may occupy nearly the same network role as a technical lead in identity while belonging to entirely different communities.
A program manager may connect three teams without being deeply embedded in any of them.
A specialist may have only four relationships but be the only person connecting a team to a critical external function.
Traditional org-network analysis often collapses these distinctions.
Instead, treat community and structural role as orthogonal variables.
4.1 Community
Run community detection on the salience-weighted backbone.
Leiden is excellent, but if the objective is to keep dependencies minimal, modern NetworkX versions include Louvain community detection.
The resolution parameter should not be chosen once and forgotten.
Sweep it.
Bootstrap interaction events.
Ask whether broadly similar community structures reappear under resampling.
A partition that changes completely when five percent of events disappear is not an organizational fact.
It is an unstable clustering result.
4.2 Structural role
For structural role, GraphWave provides an elegant idea [4].
Instead of embedding nodes according to proximity, it embeds them according to the shape of their surrounding network.
The heat kernel at scale s is:
Psi_s = U exp(-s Lambda) U'
where U and Lambda are the eigenvectors and eigenvalues of the graph Laplacian.
The heat diffusion profile around node i becomes a structural signature.
GraphWave summarizes that signature through its empirical characteristic function, producing an embedding designed to identify structurally similar nodes even when they are far apart in the network.
This is exactly what we need.
We do not necessarily want the payments lead and identity lead to be close because they interact.
We want them to be close because they play similar topological roles.
4.3 The archetypes are discovered, not imposed
Once the embeddings are clustered, the resulting groups require interpretation.
Do not assume they will always map onto the same organizational archetypes.
In practice, plausible recurring roles may include:
Hubs — actors located near the center of dense local communities.
Brokers — actors connecting communities that otherwise interact weakly.
Bottlenecks — brokers combined with directional load, queueing, or approval concentration.
Peripheral specialists — actors with relatively few but unusually salient relationships.
Connectors-of-connectors — actors with few direct relationships whose neighbors themselves occupy structurally influential positions.
Those names are hypotheses about discovered clusters.
The workflow should be:
Cluster first.
Diagnose second.
Label third.
Use degree, strength, clustering, current-flow betweenness, directional asymmetry, latency, and domain knowledge to understand what each learned role actually represents.
Cross structural role with community and the result is what I call the Role–Community Bimatrix.
It reveals not merely which teams exist, but which structural capabilities exist inside each team.
A team with no broker may be isolated.
A team whose only broker is also its primary approval bottleneck may be fragile.
A team with multiple redundant bridge roles may be much more resilient than the org chart suggests.

Caption: Figure 3. Community describes where a node participates in the interaction topology. Structural role describes the function its position appears to perform.
4.4 Approximate GraphWave implementation
def role_embeddings(
W,
scales=(1.0, 3.0, 10.0),
n_freq=12,
t_max=2.0
):
"""
GraphWave-inspired structural-role embeddings.
"""
n = W.shape[0]
degree = W.sum(axis=1)
inv_sqrt = np.divide(
1.0,
np.sqrt(degree),
out=np.zeros_like(degree),
where=degree > 0
)
Lsym = (
np.eye(n)
-
inv_sqrt[:, None]
* W
* inv_sqrt[None, :]
)
eigenvalues, U = np.linalg.eigh(Lsym)
# Avoid t = 0 because it creates constant features
ts = np.linspace(
t_max / n_freq,
t_max,
n_freq
)
features = []
for scale in scales:
Psi = (
U
* np.exp(-scale * eigenvalues)[None, :]
) @ U.T
for t in ts:
z = np.exp(1j * t * Psi)
characteristic = z.mean(axis=0)
features.append(np.real(characteristic))
features.append(np.imag(characteristic))
return np.vstack(features).TFor a research prototype, k-means is sufficient when the cluster count is known approximately. HDBSCAN or another density-based approach is more attractive when the role count itself is uncertain.
Again, the labels come after the geometry.
5. Keystone Fragility: Measuring Organizational Bus Factor with Effective Resistance
If you ask most network analysts who is structurally critical, the first answer will probably involve betweenness centrality.
Betweenness counts how often a node lies on shortest paths.
That can be useful.
But organizations do not route information like deterministic packet networks.
Information diffuses. People ask alternatives. Work gets forwarded. Teams backtrack. Someone knows someone who knows someone. A blocked route does not necessarily mean a blocked organization.
What we really want to measure is redundancy.
Electrical-network theory gives us a better abstraction.
Treat organizational interaction weights as conductances.
The effective resistance between nodes i and j is:
R_eff(i,j)
=
(e_i - e_j)' L+ (e_i - e_j)where L+ is the pseudoinverse of the graph Laplacian.
Effective resistance incorporates all available paths, not just the shortest path.
That makes it unusually appropriate for questions of structural redundancy.
The Kirchhoff index is the sum of effective resistance across all node pairs:
Kf(G)
=
N * sum_(k >= 2) 1 / lambda_kwhere lambda_k are the nonzero Laplacian eigenvalues.
However, deleting a node changes the number of pairs in the network.
Comparing Kf(G) directly with Kf(G without v) therefore creates a normalization problem: the second graph contains fewer pairs by construction.
Instead, define mean pairwise effective resistance:
R_bar(G)
=
Kf(G) / choose(N, 2)Now define Keystone Fragility:
Keystone(v)
=
[R_bar(G without v) - R_bar(G)]
/
R_bar(G)This statistic asks:
How much harder does the remaining organization become to traverse when v disappears?
If deleting v disconnects the remaining graph, assign infinite fragility.
This produces a very different ranking from shortest-path betweenness.
A high-volume actor surrounded by redundant alternatives may have substantial betweenness but modest Keystone Fragility.
A quiet specialist whose few relationships form the only viable bridge between two parts of the company may have relatively modest traffic but enormous fragility.
That is the bus-factor question we actually care about.
It is critical, however, not to confuse structural fragility with employee value.
A high score means the observed network currently relies unusually heavily on a node’s position.
It does not mean the individual is more productive.
It does not mean they should be paid more.
It does not mean another person could not take over the role after adaptation.
The metric describes the network.
Not the human.

5.1 Python implementation
def keystone_scores(W):
"""
Node-removal fragility based on mean pairwise
effective resistance.
"""
n = W.shape[0]
def mean_pairwise_resistance(Wsub):
m = Wsub.shape[0]
if m < 2:
return 0.0
L = np.diag(Wsub.sum(axis=1)) - Wsub
eigenvalues = np.linalg.eigvalsh(L)
nonzero = eigenvalues[eigenvalues > 1e-9]
if len(nonzero) < m - 1:
return np.inf
kirchhoff = m * np.sum(1.0 / nonzero)
return (
2.0
* kirchhoff
/ (m * (m - 1))
)
base = mean_pairwise_resistance(W)
scores = np.zeros(n)
for v in range(n):
remaining = [
i for i in range(n)
if i != v
]
reduced = mean_pairwise_resistance(
W[np.ix_(remaining, remaining)]
)
if np.isinf(reduced):
scores[v] = np.inf
else:
scores[v] = (
reduced - base
) / base
return scoresThis exact implementation is not appropriate for a 50,000-person company.
Repeated eigendecomposition becomes expensive quickly.
At larger scale, resistance-distance approximation, Laplacian solvers, graph sparsification, and sketching methods become necessary [5][6].
But care is needed with complexity claims.
Fast effective-resistance estimation does not automatically make every possible node-deletion counterfactual nearly linear. Large-scale Keystone analysis requires an approximation strategy designed specifically around repeated deletion or sensitivity estimation.
For low-thousands-of-nodes research prototypes, the exact calculation remains practical enough to be informative.
6. Organizational Criticality: When Communication Starts Generating Communication
Static network topology tells us who is structurally connected.
It does not tell us how activity propagates through time.
That distinction matters because organizations can enter a peculiar state in which communication begins recursively generating more communication.
A meeting creates three follow-up meetings.
A Slack message creates a thread, which creates an escalation, which creates a meeting, which creates a project-status document, which creates another meeting.
At some point, a meaningful share of organizational activity can become endogenous to the coordination system itself.
Self-exciting point processes provide a framework for analyzing that phenomenon.
6.1 The Hawkes model
For actor i, define the event intensity:
lambda_i(t)
=
mu_i
+
sum_j integral phi_ij(t-u) dN_j(u)Here:
mu_i
is the baseline or exogenous event intensity.
And:
phi_ij
describes how activity from j increases the short-run probability of subsequent activity from i.
For exponential kernels:
phi_ij(t)
=
alpha_ij * beta * exp(-beta * t)the integrated excitation coefficients form a branching matrix G.
The crucial system-level quantity is:
rho = spectral radius(G)
For the standard linear multivariate Hawkes process, stationarity requires:
rho < 1
As rho approaches one, excitation cascades become increasingly persistent.
A fitted rho greater than or equal to one does not mean the literal company is about to experience infinite meetings.
Real organizations have hard constraints.
People sleep.
Calendars fill.
Projects end.
Employees ignore messages.
Instead, rho at or above one indicates that the unconstrained stationary Hawkes specification is not an adequate description of the estimated process, or that the fitted excitation dynamics are effectively supercritical over the measured horizon.
That distinction is important.
6.2 Criticality is not endogenous share
The spectral radius should not be interpreted directly as “the percentage of communication caused by communication.”
Those are separate quantities.
Under a stationary multivariate Hawkes model, mean activity satisfies:
Lambda_bar
=
(I - G)^(-1) muThe total baseline activity is:
sum_i mu_i
while total stationary activity is:
sum_i Lambda_bar_i
A system-level endogenous share can therefore be estimated as:
endogenous share
=
1 - sum(mu) / sum(Lambda_bar)This gives us two related but different organizational metrics.
Criticality rho tells us how close the fitted excitation system is to self-sustaining cascade behavior.
Endogenous share estimates how much stationary activity is attributable to excitation rather than baseline arrivals.
The distinction makes the model considerably more interpretable.

6.3 Source and target excitation
Because G[target, source] represents excitation from a source actor into a target actor, its column sums measure source-side excitation output:
excitation_output_j
=
sum_i G[i,j]Under the branching interpretation, this approximates the expected number of first-generation downstream events associated with an event of source type j.
Row sums instead measure target-side susceptibility:
reactivity_i
=
sum_j G[i,j]This creates a potentially useful organizational distinction.
Some positions generate large downstream cascades.
Others are disproportionately drawn into cascades generated elsewhere.
But, again, interpretation requires care.
Recurring meetings can look self-exciting.
Business-hour seasonality can look self-exciting.
A major product launch can create correlated activity across everyone.
An external incident can cause dozens of teams to communicate without any team having caused another team’s activity.
A production Hawkes model therefore needs external covariates, seasonality, and event-type controls before the residual excitation matrix is interpreted organizationally.
6.4 A practical discrete approximation
A full multivariate continuous-time Hawkes estimation can become expensive.
For exploratory analysis, a nonnegative binned autoregression provides a useful approximation to excitation structure.
from scipy.optimize import nnls
def branching_diagnostics(
events,
n_nodes,
bin_hours=1.0,
n_lags=24
):
"""
Approximate Hawkes-style excitation using
nonnegative lagged count regression.
"""
timestamps = (
np.array([e["t"] for e in events])
* 24.0
)
t0 = timestamps.min()
t1 = timestamps.max()
n_bins = (
int(np.ceil((t1 - t0) / bin_hours))
+ 1
)
X = np.zeros((n_bins, n_nodes))
for e in events:
b = int(
(
e["t"] * 24.0 - t0
)
/ bin_hours
)
for participant in e["participants"]:
X[b, participant] += 1.0
lagged = []
for lag in range(1, n_lags + 1):
lagged.append(
X[
n_lags - lag:
n_bins - lag
]
)
Z = np.hstack(
lagged
+ [np.ones((n_bins - n_lags, 1))]
)
Y = X[n_lags:]
G = np.zeros((n_nodes, n_nodes))
mu = np.zeros(n_nodes)
for target in range(n_nodes):
coef, _ = nnls(
Z,
Y[:, target]
)
A = coef[:-1].reshape(
n_lags,
n_nodes
)
G[target] = A.sum(axis=0)
mu[target] = coef[-1]
rho = float(
np.max(
np.abs(
np.linalg.eigvals(G)
)
)
)
if rho < 1.0:
stationary_mean = np.linalg.solve(
np.eye(n_nodes) - G,
mu
)
total_mean = stationary_mean.sum()
if total_mean > 0:
endogenous_share = (
1.0
-
mu.sum() / total_mean
)
else:
endogenous_share = np.nan
else:
stationary_mean = np.full(
n_nodes,
np.nan
)
endogenous_share = np.nan
return {
"criticality_rho": rho,
"endogenous_share": endogenous_share,
"G": G,
"baseline": mu,
"stationary_mean": stationary_mean,
"excitation_output": G.sum(axis=0),
"reactivity": G.sum(axis=1)
}I would track these measures longitudinally rather than interpreting one snapshot in isolation.
A change following a meeting-policy intervention, reorganization, tool migration, or altered approval process is much more informative than declaring that a particular absolute value represents a “good” or “bad” organization.
This is where organizational measurement becomes experimental rather than merely descriptive.
7. Topological Genotype: What Kind of Organization Did You Actually Build?
Companies use organizational-design language constantly.
“We are decentralized.”
“We operate as autonomous pods.”
“We are a network of teams.”
“We have a hub-and-spoke model.”
“We are moving away from hierarchy.”
Those statements are usually intentions.
Network geometry lets us ask whether the observed organization actually resembles them.
Create several synthetic organizational archetypes at approximately the same scale as the observed network.
For example:
Pure tree — a conventional hierarchy with fixed span of control.
Hub-and-spoke — a dominant integration center through which most paths flow.
Modular mesh — dense team-level communities connected by sparse but redundant bridges.
Core-periphery — a dense internal core surrounded by a loosely connected fringe.
Small-world structure — strong local neighborhoods plus a smaller number of long-range shortcuts.
The problem is that the real organization and the synthetic archetype do not contain the same people.
Ordinary node-wise graph comparison therefore fails.
Gromov–Wasserstein discrepancy solves a version of this problem by comparing the relational geometry of two metric-measure spaces without requiring identical node identities [9].
Conceptually:
GW^2
=
minimum over couplings T
sum |C1[i,k] - C2[j,l]|^2
* T[i,j]
* T[k,l]C1 contains pairwise distances in the observed organization.
C2 contains pairwise distances in the archetype.
T is a coupling between positions in the two systems.
The archetype with the smallest discrepancy is the closest structural analogue.
I call that the organization’s Topological Genotype.
The value is not in saying that a company is exactly 73 percent “core-periphery.”
The value is in identifying discrepancies between designed and measured architecture.
A company may describe itself as a modular collection of autonomous teams but measure as core-periphery.
That tells us something important.
The integration work is being performed by a central relational core rather than by stable interfaces between autonomous units.
The operating model may be decentralized on paper and highly centralized in practice.

7.1 Implementation note
The Python Optimal Transport library, POT, provides several relevant solvers.
The standard Gromov–Wasserstein solver is available through:
ot.gromov.gromov_wasserstein
When entropic regularization is desired, use the explicitly regularized implementation:
ot.gromov.entropic_gromov_wasserstein
or the appropriate regularized interface available in the installed POT version.
The regularization parameter matters.
So does the choice of graph distance.
Shortest-path distance, resistance distance, and diffusion distance emphasize different structural properties.
Those choices should therefore be reported as modeling assumptions, not hidden as implementation details.
8. Conway Alignment: Does the Human Architecture Match the Technical Architecture?
Melvin Conway observed in 1968 that organizations tend to design systems reflecting their communication structures [10].
The observation became famous.
It is measured much less often than it is quoted.
Suppose we construct two matrices over the same set of teams.
The first is an organizational distance matrix:
D_comm
derived from the interaction backbone.
The second is an architectural distance matrix:
D_arch
derived from software dependencies, APIs, services, data flows, documents, workflows, or other operational dependencies.
Now calculate their matrix correlation.
Ordinary significance tests are inappropriate because pairwise observations inside a distance matrix are not independent.
The Quadratic Assignment Procedure, or QAP, addresses this by repeatedly permuting node labels and recomputing the relationship.
Let:
r_obs
=
corr(
vec(D_comm),
vec(D_arch)
)Then randomly permute one matrix:
D_arch[pi, pi]
and generate an empirical null distribution.
8.1 Python implementation
def qap_test(
D1,
D2,
n_perm=5000,
rng=None
):
"""
QAP-style permutation test for
matrix correlation.
"""
rng = (
rng
or np.random.default_rng(0)
)
upper = np.triu_indices(
D1.shape[0],
1
)
a = D1[upper]
b = D2[upper]
observed = np.corrcoef(
a,
b
)[0, 1]
exceed = 0
for _ in range(n_perm):
permutation = rng.permutation(
D1.shape[0]
)
permuted = D2[
np.ix_(
permutation,
permutation
)
]
r = np.corrcoef(
a,
permuted[upper]
)[0, 1]
exceed += (
r >= observed
)
p_value = (
exceed + 1
) / (
n_perm + 1
)
return observed, p_valueThe global correlation is useful.
The residual structure may be more useful.
Find pairs of teams with high architectural dependency but weak communication.
Those are interfaces worth investigating.
The technical systems say:
“We depend on each other.”
The human interaction system says:
“We barely coordinate.”
That is precisely the kind of mismatch that produces integration failure, ambiguous ownership, slow incident response, and the familiar postmortem sentence:
“We didn’t realize they depended on that.”
The opposite residual matters too.
If two teams communicate constantly despite little technical or workflow dependency, the organization may be paying a coordination cost inherited from an obsolete architecture, an unfinished reorganization, or poorly designed interfaces.

9. Privacy Engineering Is Part of the Model, Not a Disclaimer
Everything described so far can become organizational surveillance if implemented carelessly.
That risk does not belong in a paragraph added by Legal immediately before launch.
It changes the architecture of the system.
Metadata only
Do not ingest message content.
Not “ingest it but promise not to use it.”
Do not collect it.
Enforce the boundary at the connector layer.
Subject lines, message bodies, document contents, and sentiment analysis dramatically alter the character of the system while providing surprisingly little additional information for many structural questions.
The graph can usually be constructed from interaction metadata.
Keep it there.
Do not build individual ranking endpoints
The algorithms produce per-node quantities.
That does not mean management should receive ranked employee lists.
“Show me the ten least connected employees.”
“Rank the team by centrality.”
“Which person has the lowest influence?”
Those are not innocuous analytical requests.
They convert a structural model into a performance-management system.
If the legitimate organizational objective can be satisfied through team-level aggregation, anonymized structural-role distributions, or network-level fragility diagnostics, use those.
The cleanest way to prevent abusive queries is often not to build the endpoint capable of answering them.
Suppress thin relationships
A relationship supported by one private meeting should not suddenly appear in an analytics product.
Require minimum interaction support across multiple events and multiple days before a dyad enters a published representation.
The exact threshold depends on dataset size, organizational context, and risk model.
Do not treat a convenient value such as five events as a universal privacy standard.
And do not mistake suppression for differential privacy.
It is a disclosure-control mechanism.
Differential privacy requires sensitivity at the released-object level
Suppose a statistic f has global L1 sensitivity:
Delta_f
Under the Laplace mechanism:
private_f
=
f
+
Laplace(
Delta_f / epsilon
)The subtle point is determining Delta_f correctly.
For one fixed dyadic count, adding or removing one pairwise event changes the count by at most one.
But a hyperedge involving k participants can alter many coordinates in an entire released edge vector simultaneously.
Under the 1/(k-1) projection used earlier, the total L1 contribution across unique undirected pairs is:
choose(k, 2) / (k - 1)
=
k / 2Sensitivity therefore grows with event size unless contribution is bounded.
A serious implementation needs to define adjacency explicitly, limit or clip event contribution, compute sensitivity for the entire released object, and account for privacy loss across repeated releases.
Publishing 40 metrics each described as “epsilon = 1” does not mean the system has epsilon = 1 privacy.
Composition matters.
Give participants visibility into the measurement
Anyone represented in the system should be able to understand what data classes are collected, what features are derived, how those features are interpreted, and what outputs are visible to whom.
Where individual-level derived values are retained, giving people access to their own representation is valuable for another reason:
They will discover measurement errors.
A calendar artifact that appears statistically meaningful may be obvious nonsense to the person involved.
The people inside the system are not merely subjects.
They are part of the validation process.
Absence of interaction is not absence of contribution
This is probably the most important warning in the entire pipeline.
The engineer who created a stable library that everybody uses may generate little communication.
The researcher who solved a difficult problem alone may appear peripheral.
The employee who prevents incidents through good design may have fewer incident interactions precisely because they are effective.
Interaction data measures interaction.
It does not measure human value.
It does not measure all productivity.
It does not measure creativity.
It does not measure every form of influence.
Every downstream interface should state this explicitly because users will otherwise infer more from the numbers than the data contains.
10. Putting the Pipeline Together
The core components can be combined into a single organizational-topology report.
def org_topology_report(
events,
n_nodes,
latency_records,
t_now,
layer_weights=None
):
"""
Research-oriented organizational topology pipeline.
"""
# Salience-weighted interaction graph
W_raw = build_swin(
events,
n_nodes,
t_now,
layer_weights=layer_weights
)
# Extract multiscale backbone
W = disparity_backbone(
W_raw,
alpha=0.05
)
# Pairwise conditioned latency asymmetry
Y = np.zeros(
(n_nodes, n_nodes)
)
for (
i,
j
), (
tau_ij,
tau_ji
) in latency_records.items():
if (
tau_ij > 0
and tau_ji > 0
and W[i, j] > 0
):
value = np.log(
tau_ij / tau_ji
)
Y[i, j] = value
Y[j, i] = -value
# Hodge decomposition
hodge = hodge_decompose(
W,
Y
)
# Structural-role embeddings
roles = role_embeddings(W)
# Node-removal fragility
keystone = keystone_scores(W)
# Dynamic excitation structure
dynamics = branching_diagnostics(
events,
n_nodes
)
return {
"hierarchy_coherence":
hodge["hierarchy_coherence"],
"authority_cycle_fraction":
hodge["local_cycle_fraction"],
"remaining_cycle_fraction":
hodge["remaining_cycle_fraction"],
"latent_authority_potential":
hodge["latent_potential"],
"criticality_rho":
dynamics["criticality_rho"],
"endogenous_share":
dynamics["endogenous_share"],
"excitation_output":
dynamics["excitation_output"],
"reactivity":
dynamics["reactivity"],
"keystone_fragility":
keystone,
"role_embeddings":
roles,
"backbone":
W
}This is not a finished production system.
It is a measurement architecture.
Several important components remain outside the function: community detection, bootstrap uncertainty, archetype comparison, QAP analysis, privacy transformations, and validation against independent operational outcomes.
That separation is deliberate.
A production organizational model should not produce dozens of precise-looking metrics from a single deterministic pass and pretend uncertainty does not exist.
11. Structural Drift: Detecting When the Organization Changes Before the Org Chart Does
One of the most interesting applications of the framework is longitudinal.
Recompute the interaction graph over rolling windows.
Then compare graph spectra across adjacent periods.
Instead of the raw combinatorial Laplacian, use the normalized Laplacian so that changes in total communication volume do not automatically dominate the signal.
Let:
L_norm(t)
be the normalized Laplacian at time t.
Define spectral drift using the first k nontrivial eigenvalues:
drift(t)
=
norm(
lambda_2:k(L_norm(t))
-
lambda_2:k(L_norm(t-1))
)
Use a stable node universe where possible.
Otherwise node entry and exit themselves alter the spectrum.
A drift spike is not automatically evidence of a reorganization.
It means the relational system changed enough to deserve investigation.
Possible causes include:
A formal reorganization.
Attrition.
A product launch.
An incident.
A tool migration.
A major project.
A leadership change.
Seasonality.
A change in instrumentation.
The metric is therefore best interpreted as an organizational change detector.
Its practical value is that informal structure can change before formal structure does.
A team may begin routing decisions around a manager long before reporting lines change.
Two functions may effectively merge operationally months before leadership acknowledges the integration.
A new broker may emerge gradually because everyone discovers that one person can solve a cross-functional problem.
The shadow org chart moves continuously.
The formal org chart moves in releases.
12. What the Model Does Not Measure
The methods are powerful partly because network visualizations feel authoritative.
That makes their failure modes especially dangerous.
Channel blindness
Hallway conversations are invisible.
Phone calls may be invisible.
Lunches are invisible.
Informal conversations at an offsite are invisible.
Co-located teams can therefore appear systematically less connected than remote teams whose equivalent interaction is recorded digitally.
Location and work-mode effects must be considered before comparing organizational units.
Instrumentation changes
If a department moves from email to Slack, the organization has not necessarily changed.
The measurement apparatus changed.
Connector versions and tool migrations should be recorded as explicit interventions in every longitudinal model.
Reverse causality in response latency
A senior employee may respond slowly because of authority.
They may also respond slowly because 600 people contact them every day.
A specialist may answer an executive quickly because of hierarchy.
They may also answer quickly because the executive happens to be reporting a production incident.
Conditioning reduces confounding.
It does not eliminate it.
Validate inferred relational ordering against independent organizational information and report the degree of agreement as calibration, not proof.
Goodhart arrives immediately
The moment a metric influences organizational decisions, people can begin adapting to it.
Tell employees that cross-team centrality matters and communication volume may rise.
Tell managers that low meeting counts are desirable and meetings move off calendar.
Tell teams they are evaluated on response latency and people begin responding with meaningless acknowledgments.
Metrics alter the systems they measure.
This is another argument for keeping many of these outputs diagnostic, aggregated, and experimental rather than evaluative.
Structure is not causality
A bottleneck may correlate with slow delivery.
Removing the bottleneck does not prove delivery will accelerate.
The approval function may simply move to someone else.
The bottleneck may be a symptom of regulatory requirements.
Or the person may appear central because everybody contacts them after problems occur.
Network analysis generates hypotheses about organizational mechanism.
It does not automatically identify causal effects.
13. Where This Goes Next
The framework above remains largely descriptive.
The next interesting research problems begin when we move beyond pairwise topology.
13.1 Higher-order organizational topology
Real coordination is higher-order.
Three people in a meeting are not simply three independent dyads.
A launch committee is not reducible to the set of pairwise relationships among its members.
A cross-functional approval structure is fundamentally a multi-actor object.
That suggests working directly with simplicial complexes and hypergraphs rather than merely projecting them into ordinary graphs.
Persistent homology is particularly interesting here.
Construct a filtration over interaction strength and identify persistent first-homology classes:
H1
which correspond, loosely speaking, to robust loops without filled-in shortcuts.
An organizational loop that survives across a wide range of interaction thresholds may represent a genuinely stable coordination circuit rather than an incidental path.
This creates a mathematical route toward distinguishing temporary communication cycles from structural ones.
The area remains comparatively underexplored in applied organizational analytics.
13.2 Causal organizational structure
The natural next step is to connect topology with outcomes.
But structural metrics should not automatically be dropped into a regression as “controls.”
A network variable can be a confounder.
It can also be a mediator.
It can be caused by treatment.
It can become a collider.
Its causal role depends on the underlying data-generating process.
Reorganizations, manager transitions, approval-policy changes, broker departures, tool rollouts, and organizational redesigns create promising quasi-experimental settings.
A difference-in-differences design might compare teams affected by a structural change with appropriate comparison teams.
But the design is credible only if its identifying assumptions are credible.
Parallel counterfactual trends matter.
Anticipation matters.
Treatment timing matters.
Network spillovers matter enormously because treatment can propagate into teams formally classified as untreated.
The interesting problem is therefore not:
“Can we correlate network structure with performance?”
Of course we can.
The interesting problem is:
“Can we identify which structural interventions actually change organizational outcomes?”
That is much harder.
And much more valuable.
13.3 Graph neural networks with the right inductive bias
Hand-designed statistics encode assumptions about what matters.
A graph neural network can potentially discover structural motifs those metrics miss.
Imagine predicting incident resolution time, delivery delay, escalation probability, or handoff failure from local organizational topology.
A GNN may learn that a particular combination of brokerage, density, directional flow, and temporal excitation predicts coordination failure better than any one centrality statistic.
But there is a serious shortcut-learning problem.
The model can simply learn:
“Team X is historically slow.”
That is not organizational science.
It is entity memorization.
Training should therefore include out-of-team validation, identity masking, adversarial de-biasing where appropriate, and explicit tests for shortcut dependence.
Explanation is another problem.
Attention weights are not automatically causal explanations.
Use perturbation, ablation, counterfactual subgraphs, and dedicated graph-explanation methods to test whether inferred motifs genuinely drive predictions.
Prediction can reveal structure we failed to imagine.
But a black-box organizational score is exactly what this framework should avoid becoming.
Conclusion: The Organization You Drew Is a Hypothesis
The conventional org chart is not false.
It describes one kind of organizational truth.
It tells us where formal authority was assigned.
But companies are complex adaptive systems.
Repeated interaction creates structure.
People discover unofficial routes around bottlenecks.
Specialists accumulate influence without title changes.
Teams develop dependencies the operating model never anticipated.
New brokers emerge.
Old interfaces remain after reorganizations.
Approval chains become loops.
Communication cascades become self-sustaining.
The resulting organization is not designed in one moment.
It evolves.
And some of that evolution is measurable.
A salience-weighted interaction network can separate meaningful relational structure from raw communication volume.
Hodge decomposition can distinguish globally consistent relational ordering from local authority cycles.
Structural embeddings can separate community membership from topological role.
Effective resistance can reveal hidden fragility.
Temporal excitation models can distinguish organizational activity from organizational recursion.
Gromov–Wasserstein comparison can tell us which architecture the company has actually converged toward.
QAP can test whether the human coordination network resembles the technical system it is responsible for operating.
None of those measurements should be treated as unquestionable truth.
They are statistical representations of one slice of organizational behavior.
But they create something the traditional org chart cannot:
A falsifiable model of how the company actually coordinates.
The organization you drew is a hypothesis.
The organization in the interaction data is evidence.
The gap between them may be one of the most useful diagnostics available to a modern enterprise — provided we weight the relationships honestly, measure uncertainty, distinguish structure from causality, and refuse to turn organizational topology into a ranking system for human beings.
References
[1] Newman, M. E. J. “Scientific Collaboration Networks. II. Shortest Paths, Weighted Networks, and Centrality.” Physical Review E, 64, 016132, 2001.
[2] Serrano, M. Á., Boguñá, M., and Vespignani, A. “Extracting the Multiscale Backbone of Complex Weighted Networks.” Proceedings of the National Academy of Sciences, 106(16), 6483–6488, 2009.
[3] Jiang, X., Lim, L.-H., Yao, Y., and Ye, Y. “Statistical Ranking and Combinatorial Hodge Theory.” Mathematical Programming, 127, 203–244, 2011.
[4] Donnat, C., Zitnik, M., Hallac, D., and Leskovec, J. “Learning Structural Node Embeddings via Diffusion Wavelets.” Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining, 2018.
[5] Klein, D. J., and Randić, M. “Resistance Distance.” Journal of Mathematical Chemistry, 12, 81–95, 1993.
[6] Spielman, D. A., and Srivastava, N. “Graph Sparsification by Effective Resistances.” SIAM Journal on Computing, 40(6), 1913–1926, 2011.
[7] Hawkes, A. G. “Spectra of Some Self-Exciting and Mutually Exciting Point Processes.” Biometrika, 58(1), 83–90, 1971.
[8] Hawkes, A. G., and Oakes, D. “A Cluster Process Representation of a Self-Exciting Process.” Journal of Applied Probability, 11(3), 493–503, 1974.
[9] Peyré, G., Cuturi, M., and Solomon, J. “Gromov-Wasserstein Averaging of Kernel and Distance Matrices.” Proceedings of the 33rd International Conference on Machine Learning, 2016.
[10] Conway, M. E. “How Do Committees Invent?” Datamation, 14(4), 28–31, 1968.
[11] Krackhardt, D. “QAP Partialling as a Test of Spuriousness.” Social Networks, 9(2), 171–186, 1987.
[12] Dwork, C., McSherry, F., Nissim, K., and Smith, A. “Calibrating Noise to Sensitivity in Private Data Analysis.” Theory of Cryptography Conference, 2006.
[13] Kivelä, M., Arenas, A., Barthelemy, M., Gleeson, J. P., Moreno, Y., and Porter, M. A. “Multilayer Networks.” Journal of Complex Networks, 2(3), 203–271, 2014.
[14] Callaway, B., and Sant’Anna, P. H. C. “Difference-in-Differences with Multiple Time Periods.” Journal of Econometrics, 225(2), 200–230, 2021.
Code in this article is intended to make the methodology transparent rather than provide a production-ready organizational-surveillance platform. Dense eigendecomposition, explicit triangle enumeration, repeated node-deletion calculations, and full pairwise matrices become expensive at enterprise scale. Production implementations should use sparse representations, iterative Laplacian solvers, bounded-memory streaming pipelines, privacy-preserving aggregation, explicit uncertainty estimation, and governance controls designed before deployment rather than after it.
About the Author
Brian Curry is a Kansas City–based AI and Machine Learning researcher, data scientist, and the founder of Vector1 Research, where he works on the intersection of cognitive AI architecture, causal inference, and economic systems. His research introduced Memory-Node Encapsulation (MNE), an original data structure for artificial episodic memory, and the NeoCortex-M architecture for memory-driven AI. He is the creator of Papilon, an open-source framework for complex system optimization with agentic orchestration, PyCausalSim, a Python framework for causal discovery through simulation, and Daedalus, a platform for causal and economic analysis.
His practitioner work focuses on building production intelligence systems — causal marketing analytics, agentic systems, and the serving infrastructure that makes them deployable inside enterprise environments. He writes about that work at vector1.ai and on Medium.


