Skip to content

Phase 5: optional [graph] analysis layer + core scalars - #5

Merged
zolizoli merged 1 commit into
mainfrom
phase-5-graph
Jul 1, 2026
Merged

Phase 5: optional [graph] analysis layer + core scalars#5
zolizoli merged 1 commit into
mainfrom
phase-5-graph

Conversation

@zolizoli

Copy link
Copy Markdown
Member

Phase 5 — analysis

The optional analysis layer that produces real encoding channels, plus the dependency-free core scalars. Stacked on #4. The dependency arrow points inward: the core never imports analyze.

Core (no extra)

  • lexograph.scalarslengths, positions, frequencies: the built-in channel sources, so a walk/spiral/dotplot works with nothing installed beyond the core.

lexograph[graph] extra

  • analyze/embeddings.pyembed_sentences (sentence-transformers, L2-normalised). The heavy import is deferred to call time, so importing analyze is cheap and the whole pipeline is testable with injected vectors.
  • analyze/graph.pyknn_graph (cosine kNN), embedding_distances (→ semantic recurrence dotplot), pagerank_scores (size), community_labels (colour; Louvain default, KMeans option).
  • analyze/backbone.py — disparity-filter backbone, ported from sibling kenon (Serrano et al. 2009).
  • analyze_textAnalysis — aligned size / community / distances arrays from a text. embeddings are injectable.
a = analyze_text(load_demo_text())               # PageRank + Louvain + distances
text_walk(load_demo_text(), colour=a.community, colour_kind="categorical", size=a.size)
recurrence_plot(load_demo_text(), distances=a.distances, threshold=0.35)

Verification

  • make ci green: ruff + ty + 180 tests / 1 skipped. The graph pipeline (kNN, PageRank, Louvain/KMeans, disparity backbone, analyze_text) is covered with synthetic embeddings — no model download. The real embedder is an opt-in smoke test (LEXOGRAPH_RUN_MODEL=1).
  • mkdocs build --strict green — mkdocstrings/griffe static-analyses analyze without importing the heavy deps (same pattern the family's RTD uses, which installs only the docs extra).
  • pyproject gains the [graph] extra; uv.lock regenerated.

🤖 Generated with Claude Code

Port the Wittgenstein analysis pipeline behind an extra; keep simple
scalars dependency-free in the core. The arrow points inward — the core
never imports analyze.

- scalars.py (core): lengths / positions / frequencies, the dependency-free
  channel sources.
- analyze/ ([graph] extra):
  - embeddings.py: embed_sentences (sentence-transformers, L2-normalised;
    the heavy import is deferred to call time).
  - graph.py: knn_graph (cosine kNN), embedding_distances (semantic
    recurrence input), pagerank_scores (size), community_labels (colour;
    Louvain default, KMeans option).
  - backbone.py: disparity-filter backbone, ported from kenon (Serrano 2009).
  - analyze_text -> Analysis: aligned size / community / distances arrays
    from a text (embeddings injectable, so the pipeline tests need no model).
- pyproject: [graph] extra (sentence-transformers, scikit-learn, networkx,
  scipy); uv.lock updated. Exports, example, docs, CHANGELOG.

Pipeline fully tested with synthetic embeddings (no download); the real
embedder is an opt-in smoke test (LEXOGRAPH_RUN_MODEL). ruff + ty + 180
tests green; mkdocs build --strict green (griffe static-analyses analyze
without importing the heavy deps).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zolizoli zolizoli mentioned this pull request Jun 30, 2026
@zolizoli
zolizoli changed the base branch from phase-4-grids to main July 1, 2026 09:30
@zolizoli
zolizoli merged commit 7c6eae5 into main Jul 1, 2026
@zolizoli
zolizoli deleted the phase-5-graph branch July 1, 2026 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant