Skip to content

feat(loom): configurable fusion threshold, edge dedup fix, and graph-build E2E coverage#77

Open
tongshu2023 wants to merge 1 commit into
zijinz456:mainfrom
tongshu2023:claude/issue-38-loom-mvp
Open

feat(loom): configurable fusion threshold, edge dedup fix, and graph-build E2E coverage#77
tongshu2023 wants to merge 1 commit into
zijinz456:mainfrom
tongshu2023:claude/issue-38-loom-mvp

Conversation

@tongshu2023

Copy link
Copy Markdown

Summary

Addresses the remaining LOOM MVP checklist items from #38. Of the backend checklist, consolidation triggers (_consolidate_mastered_concepts, threshold 0.85 → parent boost) and cross-course linking (link_cross_course_concepts) already exist in the codebase — what was missing was the configurable fusion threshold and the end-to-end test, plus a real bug the new E2E test surfaced.

Changes

1. LOOM_FUSION_SIMILARITY_THRESHOLD is now a setting

config.py gains loom_fusion_similarity_threshold: float = 0.85. _fuse_concepts resolves it at call time via _fusion_threshold(), so deployments can tune fusion aggressiveness through the environment without a code change. Falls back to the module default when settings are unavailable (isolated unit tests).

2. Bug fix: duplicate edge insertion fails the whole graph build

Surfaced by the new E2E test running against real SQLite instead of mocks: when the same concept is extracted from multiple content chunks and embedding fusion is unavailable (no embedding provider configured — a common deployment), edge creation re-emitted identical (source, target, relation_type) rows. The uq_knowledge_edge constraint then aborted the commit, failing the entire graph build. The existing mocked tests could not catch this because mock sessions don't enforce constraints.

Edge creation now dedupes on (source_id, target_id, relation_type).

3. E2E test: upload → auto-build graph → verify nodes/edges

tests/test_loom_graph_e2e.py, on real in-memory SQLite (aiosqlite + Base.metadata.create_all), following the house pattern from test_learning_pipeline_e2e.py:

  • content upload → build_course_graph → persisted nodes verified by name/description/bloom metadata, prerequisite and related edges verified by direction
  • rebuild is idempotent (no duplicate nodes)
  • course with no content builds nothing
  • Graphusion fusion merges near-duplicate concepts and unions their relationships
  • the configured threshold changes fusion behavior (0.999 keeps cosine-0.994 near-dupes separate)
  • cross-course linking creates bidirectional reinforces edges exactly once, and re-linking does not duplicate

Tests

tests/test_loom_graph_e2e.py (6 new) + tests/test_loom.py: 43 passed locally.

Checklist mapping

  • Graph fusion deduplication (threshold: LOOM_FUSION_SIMILARITY_THRESHOLD=0.85) — threshold now configurable; chunk-duplicate edge bug fixed
  • Cross-course concept linking — already implemented; now covered end-to-end
  • Consolidation triggers — already implemented in loom_mastery.py (CONSOLIDATION_THRESHOLD = 0.85, parent boost 0.1)
  • End-to-end test: upload content → auto-build graph → verify nodes/edges

🤖 Generated with Claude Code

…d E2E coverage (zijinz456#38)

Closes out the remaining LOOM MVP checklist items from zijinz456#38:

- Surface the Graphusion fusion similarity threshold as a setting
  (LOOM_FUSION_SIMILARITY_THRESHOLD, default 0.85) resolved at call
  time, so deployments can tune fusion aggressiveness without a code
  change. Falls back to the module default when settings are
  unavailable.
- Fix a real edge-insertion bug surfaced by the new E2E test: when the
  same concept is extracted from multiple chunks and embedding fusion
  is unavailable (no embedding provider configured), identical edges
  were emitted repeatedly and violated uq_knowledge_edge at commit,
  failing the whole graph build. Edge creation now dedupes on
  (source, target, relation_type).
- Add tests/test_loom_graph_e2e.py: end-to-end content upload ->
  build_course_graph -> persisted node/edge verification on real
  in-memory SQLite (not mocks), idempotent rebuild, no-content course,
  fusion dedup of near-duplicate concepts, threshold override behavior,
  and bidirectional cross-course reinforces linking without duplicates.

Consolidation triggers and cross-course linking from the checklist
already exist in loom_mastery.py / loom_graph.py; this PR verifies the
latter end-to-end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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