Skip to content

core.complex

core.complex

Outer-ring residue of the reasoning complex (dn-inner-outer-core §2.7, K1 / bp-090).

The pure family-5 mathematics (balance, curvature, hodge, laplacian, support + the package's inner init text) moved to core/kernel/complex/. What remains here is the outer half — the modules whose closure leaves the admissible base: spectral (sknetwork), topology (ripser), temporal (duckdb), and the blocks/build/cut assembly that reaches them. This init is stdlib-import-free so it stays inner by construction (a pure package marker); the residue submodules beside it are the outer machinery.

blocks

Degree-corrected stochastic block model — themes with a posterior (companion III §6.2; H7).

The spectral clusterer gives a point partition and makes you pick k. The SBM is generative: it says how likely each note belongs to each theme (a posterior, not a guess) and how many themes the data support (model selection). Degree correction (Karrer–Newman) keeps a prolific topic from swallowing the graph.

Light implementation, per the BUILD §2.2 disposition ("custom, ~200 lines, VEM; keep it thin"): a mean-field variational EM for the Poisson DC-SBM —

E:  log q_i(r) ∝ log π_r + Σ_j A_ij Σ_s q_js log ω_rs − d_i Σ_s κ_s ω_rs
M:  m_rs = qᵀA q,   κ_r = Σ_i q_ir d_i,   ω_rs = m_rs/(κ_r κ_s),   π_r = n_r/n

initialized from the deterministic diffusion embedding (fixed-seed k-means), run a fixed number of rounds — fully deterministic. Model selection by an ICL/BIC-style penalized complete-data likelihood (the Karrer–Newman objective minus a parameter-count penalty); the exact penalty is a declared engineering choice validated on planted graphs (the block-recovery property test), not a derived MDL bound — stated honestly.

The line held (§6.3): the posterior organizes the graph (membership), it never certifies a thought. Deterministic; model-free; no network.

SBMResult dataclass

The fitted blocks: hard labels, the n×k membership posterior, the model-selected k, and the ICL score per candidate k (the model-selection trace, for the cross-check).

labels instance-attribute
posterior instance-attribute
k instance-attribute
icl_by_k instance-attribute

sbm(A, *, k_max=8)

Fit the DC-SBM for k = 1..k_max and select k by the penalized objective (ICL/BIC style):

ICL(k) = L_KN(k) − ½·[k(k+1)/2]·ln W − ½·(k−1)·ln n,      W = total edge weight.

Returns the winning k's posterior + hard labels. Deterministic end to end.

build

build_complex(view) — assemble the reasoning complex 𝔎 from a MirrorView (companion III §1).

The object the strong Dreamer reasons over, regenerated per trough pass (never a long-lived global, §1.3):

  • nodes — one per authored note (its digest), from a MirrorView only, so a non-authored complex is unrepresentable (Invariant 6, structural firewall — the constructor's type IS the proof);
  • A — the weighted similarity backbone (cosine over note centroids, negatives/self zeroed);
  • A_signed — the signed adjacency: A with polarity overlaid from any persisted typed edges (EdgeStore; contradiction ⇒ −w). With no persisted edges it equals A (pure support), so the similarity backbone is a balanced signed graph until a contradiction is asserted;
  • hyper — the derivation B-arcs (tail set → head) touching these nodes, from the DerivedStore junction (companion III §1.3); empty for a pure authored view.

Deterministic (fixed embeddings ⇒ fixed graph), model-free, Zone A (no network).

ReasoningComplex dataclass

𝔎|_MR — the introspective reasoning complex over authored notes (companion III §1.5).

A small immutable snapshot: the node list + index, the weighted (A) and signed (A_signed) adjacencies, the derivation hyperedges, and per-node layer/creation arrays for §5.4 temporal tracking. Assembled by build_complex from a MirrorView; the Laplacian/spectral/balance modules consume it. Never mutated — a fresh pass rebuilds it (regenerable).

nodes instance-attribute
idx instance-attribute
A instance-attribute
A_signed instance-attribute
hyper instance-attribute
layers instance-attribute
created instance-attribute
titles = field(default_factory=dict) class-attribute instance-attribute
n property

cosine_adjacency(vectors, *, sim_floor=0.0)

Weighted cosine-similarity adjacency: symmetric, zero diagonal, negatives clamped to 0, and entries below sim_floor dropped (denoising). Zero vectors sit at the origin (no edges).

The similarity backbone A (companion III §2.2). Deterministic. For the lexical/semantic embeddings the Dreamer uses, orthogonal notes have 0 cosine, so A is naturally sparse.

build_complex(view, *, edges=None, derived=None, sim_floor=0.0)

Assemble 𝔎|_MR from a MirrorView (Invariant 6: authored-only is structural — the input type cannot hold a non-authored row).

edges (optional EdgeStore): persisted typed/signed edges overlaid onto A_signed, so an asserted contradiction flips a pair's polarity to −w. derived (optional DerivedStore): the derivation hyperedges whose tails touch these authored nodes. Both default None (pure similarity backbone, no hyperedges), keeping the introspective pass self-contained.

cut

Min-cut-to-authored + conductance — the alignment detector (companion III §3.5; H6/A2).

The same "distance against ground" move as the drift gauge, on the graph:

  • conductance Φ(S) = w(∂S) / min(vol S, vol S̄) — how sealed-off a community is from the rest of the mirror. A community whose conductance is falling over time is becoming an echo chamber (Cheeger: ½λ₂ ≤ Φ ≤ √(2λ₂) ties it to the spectral family). The A2 axis is the worst (minimum) community conductance.
  • grounding cut — for an interpreted artifact, the min cut (= max flow) separating it from the authored leaves through its derivation refs. Multi-path support through many refs ⇒ a large cut; everything funnelled through one weak parent ⇒ a small one. Adding an authored support edge can never lower it (monotone — capacities only ever increase).

Exact, deterministic, model-free. Max-flow uses scipy.sparse.csgraph.maximum_flow, which needs integer capacities: unit-weight refs are integers already; fractional weights are fixed-point scaled (documented at the constant). These feed the drift gauge's additive structural axes (eval/drift.py, the A2 extension) — detection only, nothing here alters anything.

conductance(A, S)

Φ(S) = w(∂S) / min(vol S, vol S̄) over the weighted adjacency. 0 ⇔ S is disconnected from the rest; 1-ish ⇔ S is not a community at all. Degenerate S (empty / everything / zero volume) returns 0.0 — maximally sealed, the conservative reading for an alignment detector.

min_conductance(A, labels=None)

The worst (minimum) community conductance over a partition — the A2 echo-chamber axis. labels defaults to the deterministic spectral partition. Communities of size < 2 are skipped (a singleton is not a chamber). No community ⇒ 1.0 (nothing sealed off, healthy).

grounding_cut(refs_of, artifact, authored)

The min cut separating artifact from the authored leaves through the derivation refs (refs_of: artifact id -> its derived_from refs; a ref is either another artifact id or an authored digest). Unit capacity per ref edge — the cut counts how many refs must be severed to disconnect the artifact from ground. 0 ⇔ ungrounded (no path to an authored leaf).

Monotone in support: adding a ref (an authored support edge) only ever adds capacity, so the cut never decreases — the metamorphic property the A2 detector rests on.

alignment_snapshot(kx)

The A2 structural axes for the drift profile, computed on one complex snapshot:

  • frustration — λ_min(L̄) of the signed adjacency (rising = growing dissonance);
  • min_conductance — worst community conductance (falling = an echo chamber forming).

Detection only; the caller (a snapshot writer / the drift harness) feeds these into eval.drift.ProfileAxis is additive, so this is a data change, not a rewrite (A2).

spectral

Spectral & diffusion clustering (companion III §2.2) — the principled clusterer.

The bottom eigenvectors of the symmetric-normalized Laplacian are the graph Fourier basis; the Fiedler value λ₂ is algebraic connectivity; spectral/diffusion clustering partitions by those bottom modes. This replaces the cosine single-linkage floor and dissolves the chaining that forced σ = 0.50 in F9: single-linkage merges any two notes joined by a weak bridge, whereas the normalized cut respects global density, so a dense theme is recovered whole and a weak inter-theme bridge is cut.

Deterministic: partial eigensolves use a fixed ARPACK start vector; k-means uses a fixed seed. No model, no network. Clustering is done per connected component (distinct components are never merged) with the eigengap heuristic choosing k within each; components smaller than min_size and isolated notes are dropped, matching the single-linkage clusterer's contract.

fiedler(A)

(λ₂, Fiedler vector) of L_sym — algebraic connectivity and the smallest nontrivial mode. λ₂ ≈ 0 signals a weak cut (a near-disconnection); its eigenvector bisects the graph (§2.2).

diffusion_map(A, *, n_components=8, t=1.0)

Diffusion-map coordinates: the nontrivial bottom eigenvectors of L_sym scaled by the heat weight e^{-tμ} (companion III §2.2). Row i is note i's position in diffusion space; Euclidean distance there is the diffusion distance at scale t. Deterministic.

estimate_k(vals, *, k_max)

Eigengap heuristic: k = the index of the largest gap among the smallest eigenvalues, bounded to [1, k_max]. A clean k-community graph has k small eigenvalues then a jump.

spectral_labels(A, *, k_max=8)

A cluster label per node over the whole graph: connected components are clustered independently (never merged) and their labels offset into a single global labeling.

louvain_labels(A, *, resolution=1.0)

Modularity (Louvain) community labels via scikit-network — a second, independent method to cross-check the spectral partition (companion III §2.3: three methods cross-checked; disagreement = a fragile theme). Deterministic (fixed random_state). Not on the live path — a diagnostic the strong-Dreamer pass can compare against spectral_labels.

diffusion_cluster_notes(notes, *, threshold=0.62, min_size=2, k_max=8, sim_floor=None)

Diffusion/spectral clustering over note centroids — a drop-in for cluster.cluster_notes (same signature + return type) that the Dreamer/adapter can select behind the seam.

The graph is the weighted cosine backbone with a light denoising sim_floor (default a third of threshold, capped at 0.15) — deliberately below the single-linkage cut, because spectral structure, not a hard threshold, separates the themes. Returns Clusters of ≥ min_size, largest first (ties by first member's title), fully deterministic.

temporal

Structural snapshots — the system watching its own structure evolve (§5.4; H9).

The valuable temporal program is not a PDE but a time series of structural invariants: compute β₀, the Fiedler value, frustration, the curvature distribution, the SBM theme count, the worst community conductance, the H₁ hole count, and (design note dn-edge-dynamics §2.3, bp-022) the two degree-1 invariants — dim ker L₁ (β₁ of the flag complex, exact) and total harmonic persistence (Σ lifetime over long-lived holes) — at each trough pass; watch how they move. A rising frustration, a community whose conductance is falling, a domain fragmenting, a thread count that grows — each is a measurable trajectory. This is exactly the input the drift gauge (A1/A2) and the longitudinal harness (F4) want.

Wall-clock time τ (the graph actually changing) — NOT diffusion time t (a resolution knob on a frozen snapshot); keeping them distinct is §5.1's discipline. Snapshots are DuckDB (the telemetry convention for quantitative time-series), in their own file beside the derived store — derived, regenerable-in-principle data, never the mirror. Detection only: nothing here alters anything.

StructuralSnapshot dataclass

One trough pass's structural invariants (the §5.4 / BUILD §1.2 row).

taken_at instance-attribute
n_nodes instance-attribute
n_components instance-attribute
fiedler instance-attribute
frustration instance-attribute
mean_forman instance-attribute
frac_neg_curv instance-attribute
n_blocks_sbm instance-attribute
min_conductance instance-attribute
persistence_h1 = None class-attribute instance-attribute
dim_ker_l1 = None class-attribute instance-attribute
harmonic_persistence_total = None class-attribute instance-attribute
structural_axes()

The A2 drift axes this snapshot feeds (eval.drift.Profile optional fields). The drift-axes contract is CONSUMED (design note §3 risk) — the degree-1 fields are additive observation, never added here; this stays byte-identical to before bp-022.

SnapshotStore dataclass

Append-only DuckDB store of structural snapshots + the trajectory readers the drift gauge (A2) and the F4 longitudinal harness consume.

path instance-attribute
write(snap)
count()
trajectory(metric)

The time series of one invariant, oldest first — the F4 drift-trajectory input. metric is validated against the schema (no SQL injection by column name).

latest_structural()

The most recent snapshot's A2 axes — directly consumable by eval.drift.profile_from_report(structural=...). None when no snapshot exists.

close()

compute_snapshot(kx, *, distances=None, sbm_k_max=8, hole_min_persistence=0.15, thread_min_persistence=0.15, taken_at=None)

Compute the invariants on one complex. Deterministic, model-free. distances (the unthresholded cosine-distance matrix) enables the H₁ count and the two degree-1 invariants (design note dn-edge-dynamics §2.3, bp-022 §6(c)); None records NULL rather than a fake zero (the persistence filtration cannot run on the thresholded backbone alone). dim_ker_l1 is the kernel dimension of kx.A's Hodge 1-Laplacian at σ (exact, cheap at fixed scale — bp-021's cross-check harness guarantees agreement with the ripser alive-count, plan §6(c) / parked decision "snapshot β₁ source"); harmonic_persistence_total sums lifetime over holes at least thread_min_persistence long — the same filtration long_lived_holes already runs for persistence_h1, just re-thresholded and summed rather than counted.

open_snapshot_store(config=None)

topology

Flag complex + persistent H₁ — conceptual holes (companion III §4; H5).

Persistence runs over the flag (clique) complex K_σ of the similarity graph: sweep the cosine-distance threshold (Vietoris–Rips filtration — Rips is the flag complex of the distance graph), track when cycles are born and die. A long-lived H₁ feature is a conceptual hole: notes pairwise related in a ring with no center tying them together — "you orbit this without stating it". The bottleneck stability theorem makes the diagram a stable diagnostic (it moves no more than the input perturbation).

What H₁ is NOT (the §4.2 correction, load-bearing): a 1-cycle is a topological hole — NEVER a logical contradiction (that is a signed/semantic property, routed through balance.py) and NEVER circular reasoning (structurally impossible on the acyclic derives-DAG). Route dissonance through balance/frustration; route gaps through here. Holes are a utility-axis prompt (what to look at), not a belief claim.

ripser (the BUILD §2.2-adopted C++ backend) is imported lazily inside the compute call — it drags in plotting libs we never use at module import. Deterministic; no model; no network.

Hole dataclass

One long-lived H₁ feature: a conceptual hole in the flag complex.

vertices is a deterministic witness on the cycle (the representative cocycle's endpoints, completed into a cycle through the birth-scale graph) — the notes that circle the hole. A witness, not the unique minimal cycle (which is not well-defined in general).

birth instance-attribute
death instance-attribute
vertices instance-attribute
lifetime property

cosine_distance_matrix(vectors)

1 − cosine similarity, symmetric, zero diagonal — the Rips filtration input. Zero vectors sit at distance 1 from everything (orthogonal), matching the backbone's convention.

persistence(D, *, maxdim=1)

Vietoris–Rips persistence over a distance matrix via ripser (lazy import). Returns the raw ripser output (dgms, cocycles, …) — exact and deterministic for a fixed input.

long_lived_holes(D, *, min_persistence)

The H₁ features with lifetime ≥ min_persistence, each with a cycle witness — the conceptual holes worth surfacing. Sorted longest-lived first (ties by birth), deterministic.