# Changelog

All notable changes to the Arandu SDK.

## v0.6.29 — DX Polish + ScoredFact Rename

- **fix!:** `ScoredFact.value` renamed to `ScoredFact.fact_text` for clarity
- **feat:** `min_score` config parameter — filters facts below threshold from results (default 0.0)
- **fix:** Mermaid pipeline diagram updated (removed stale single_pass references)
- **docs:** CHANGELOG updated through v0.6.29
- **docs:** MemoryConfig full reference page added
- **docs:** Database schema reference page added

## v0.6.28 — Remove Single-Pass Mode

- **feat!:** Removed `single_pass` extraction mode entirely — `multi_pass` is the only mode
- **feat!:** Removed `extraction_mode` config parameter
- **feat!:** Removed reflexion pass (was single-pass only)
- **refactor:** ~150 lines of code removed from `extract.py`

## v0.6.27 — Semantic Dedup

- **feat:** Post-extraction semantic dedup via embedding cosine similarity (threshold 0.85)
- **feat:** Reduces cross-entity reformulations ("Vertix was co-founded by Ricardo" when "Ricardo co-founded Vertix" exists)
- **result:** Multi-pass facts dropped from 147 → 85 (vs 88 GT) over benchmark evolution

## v0.6.26 — Mirror Fact Matcher Improvement

- **fix:** Relation-to-fact matcher now searches ALL created facts (not just source/target entity keys)
- **fix:** Reduces unnecessary mirror fact creation when a cross-entity fact already covers the relationship

## v0.6.25 — Extraction Prompt Rewrite

- **fix:** Strong "NO DUPLICATE INFORMATION" rule added to extraction prompts
- **fix:** Multi-pass facts dropped from ~147 to ~105 in benchmark
- **refactor:** Prompts restructured with numbered rules for better LLM compliance

## v0.6.24 — Fact-Entity Links (Part 3)

- **feat:** Importance scoring counts `fact_density` via `MemoryFactEntityLink` (cross-entity coverage)
- **refactor:** Extraction prompts cleaned — removed restrictive dedup rule, replaced with soft "most natural subject" guidance

## v0.6.23 — Fact-Entity Links (Part 2)

- **feat:** Graph retrieval and spreading activation query facts via `MemoryFactEntityLink` instead of direct `entity_key` match
- **feat:** Cross-entity retrieval — "Clara left Vertix" found when querying about Vertix via secondary entity link
- **feat:** Fallback to direct `entity_key` match for backward compatibility

## v0.6.22 — Fact-Entity Links (Part 1)

- **feat:** New model `MemoryFactEntityLink` — links each fact to ALL entities it mentions
- **feat:** Write pipeline creates entity links after every ADD/UPDATE (primary + secondary via substring match)
- **feat:** Fail-safe link creation — fact persists even if link creation fails

## v0.6.21 — Self-Contained Facts + Dedup Fix

- **fix:** Facts now always include entity name in text ("Fernanda Lima is a software engineer", not "is a software engineer")
- **fix:** Exact dedup strips trailing punctuation before comparing
- **fix:** Single-pass extraction now deduplicates (was missing)
- **refactor:** Extracted `_deduplicate_facts()` as shared function for both extraction modes

## v0.6.20 — Prompt Cleanup + Batch Removal

- **feat!:** Removed multi-pass batching — all entities go in a single fact extraction call (3 LLM calls total: scan + facts + relations)
- **refactor:** Extraction prompts made domain-agnostic (removed corporate jargon like "squad", "tribe", "reporting chain")
- **fix:** Subject-centric extraction prompt added to reduce cross-entity duplication

## v0.6.19 — Relationship-Fact Pairing

- **fix:** Every relationship now also generates a corresponding fact (e.g., `spouse_of` relation creates "Sarah is user's wife" fact)
- **fix:** Relationship-fact pairing rule added to both single-pass and multi-pass prompts

## v0.6.18 — Free-Form Entity Types

- **fix!:** Entity types changed from `Literal["person", "organization", "place", "pet", "other"]` to free-form `str`
- **feat:** Entity types normalized to lowercase during resolution (`"Person"` → `"person"`)
- **refactor:** Extraction prompts suggest common types without enforcing a closed set

## v0.6.17 — Benchmark Infrastructure (Part 2)

- **feat:** `config_overrides` parameter added to `write()` (same pattern as `retrieve()`)
- **feat:** `dry_run=True` parameter for `write()` — runs extraction without persisting
- **feat:** `config_effective` dict added to `WriteResult` (shows actual config used)

## v0.6.16 — Benchmark Infrastructure (Part 1)

- **feat!:** `LLMProvider.complete()` now returns `LLMResult(text, usage)` instead of `str`
- **feat:** `TokenUsage` dataclass with `input_tokens`, `output_tokens`, `total_tokens`
- **feat:** `tokens_used` field added to `WriteResult` and `RetrieveResult`
- **feat:** Built-in `OpenAIProvider` reports token usage automatically

## v0.6.15 — DX Documentation Overhaul

- **docs:** Plain-English intros added to every stage of read pipeline, write pipeline, and background jobs
- **docs:** Entity resolution visual walkthrough with mermaid diagram
- **docs:** 14 DX issues from inspector review addressed
- **docs:** Spreading activation dataset threshold guidance added

## v0.6.14 — Config Enforcement + Observability

- **feat:** `config_overrides` parameter added to `retrieve()`
- **fix:** `spreading_activation_hops=0` now properly disables spreading (no DB queries)
- **fix:** `spreading_decay_factor` and `spreading_facts_per_entity` now consumed from config (were hardcoded)
- **fix:** Reranker timeout enforced via `asyncio.wait_for`
- **feat:** Spreading activation observability added to retrieval trace

## v0.6.13 — Deterministic Entity Resolution

- **feat:** 3-layer deterministic entity resolution for read pipeline (alias + display_name + slug match)
- **feat:** Graph signal no longer depends on LLM planner for entity extraction
- **feat:** Entity sources tracked in retrieval trace (`entities_sources: {llm, deterministic, expansion}`)
- **fix:** LLM entity normalization (`entity:Carlos` → `person:carlos`)
