Completed
2 months
Solo project

Moire

Moire is a personal reflection system that transforms unstructured journal entries into a living semantic map of thoughts, emotions, habits, and identity. Instead of encouraging users to reread old entries, the system surfaces patterns over time — what themes recur, how ideas connect, and how the user's inner landscape evolves.

Journal entries are processed through a multi-stage NLP pipeline that segments text into coherent thematic chunks, extracts high-level topics and sentiment, canonicalises those topics into persistent conceptual nodes, and builds weighted connections between them across time. The result is a dynamic graph where nodes represent meaningful concepts in the user's life and edges represent how those concepts co-occur and evolve together.

The project is driven by a core question: How can reflection support growth without forcing people to manually look backward? Rather than presenting raw logs, Moire acts as a reflective mirror — revealing identity, motivation, struggles, and growth as emergent structure rather than explicit memory recall.

Moire

Tools & Technologies

Next.jsReactJavaScriptTailwind CSSPrisma ORMPostgreSQLClerkOpenAI APIESLint

Project Overview

Status: Completed
Duration: 2 months
Team Size: Solo project

Key Takeaways

  • Designed and implemented an end-to-end semantic processing pipeline using LLMs, embeddings, and graph-based representations
  • Built a canonicalisation system that maps noisy, LLM-generated topics into stable conceptual nodes using embedding similarity, centroid updates, and LLM fallback checks
  • Implemented semantic chunking to preserve context while enabling fine-grained insight extraction without over-fragmentation
  • Used vector embeddings and cosine similarity to manage concept identity, merging, and drift over time
  • Architected a clean separation between API orchestration and core domain logic, improving extensibility and testability

Challenges Overcome

  • Preventing topic explosion and semantic drift from LLM outputs by introducing TopicAlias mapping and node centroids
  • Balancing automation vs interpretability, deciding when to trust embedding similarity and when to defer to LLM reasoning
  • Preserving contextual meaning while chunking entries, especially when themes reappear non-linearly
  • Designing a graph system that evolves incrementally without regenerating or invalidating existing structure
  • Avoiding 'therapy-bot' failure modes by constraining tone, scope, and assumptions in reflective summaries

Interested in This Project?

Check out the code or see it in action!