Skip to content

Commit 1073b33

Browse files
author
Flamehaven CI
committed
release: v1.6.1 — code quality pass + hybrid search + mixin refactor
v1.6.0 — BM25+RRF hybrid search, KnowledgeAtom chunk indexing, stable URI scheme, core.py mixin segmentation (1258->221 lines), multi-provider LLM, framework SDKs. v1.6.1 — code quality: - api.py: initialize_services decomposed (_init_searcher/_init_cache/_init_metrics); _record_upload_failure extracted to eliminate duplicate metrics blocks - admin_routes.py: _get_admin_user (CC~10) -> _parse_bearer_token + _try_oauth_admin + _resolve_key_admin + 5-line orchestrator - engine/chronos_grid.py: seek_vector_resonance -> _hnsw_vector_resonance + _brute_vector_resonance dispatch - engine/gravitas_pack.py: _compress_dict/_decompress_dict clone cluster -> _transform_dict dispatch table - eval_self.py: CORPUS_FILES split into AUDIT_CORPUS (docs) + SOURCE_CORPUS - .gitignore: docs/history/, slop artifacts, .cr-ep/ added Tests: 475 passed, 13 skipped
1 parent 1b538bb commit 1073b33

28 files changed

Lines changed: 6142 additions & 4556 deletions

.gitignore

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ doc_sanity_report*.json
156156
DOC_SANITY_FIXES.md
157157
PHASE*_COMPLETION_SUMMARY.md
158158

159+
# Historical development artifacts (internal audit reports, design docs — not public docs)
160+
docs/history/
161+
159162
# Test data
160163
test_files/
161164
sample_data/
@@ -174,6 +177,16 @@ logs/
174177
*.sqlite
175178
*.sqlite3
176179

177-
# SIDRCE reports (internal quality metrics)
180+
# SIDRCE reports and slop-detector outputs (internal quality metrics)
178181
sidrce_report*.json
182+
sidrce_cert*.yaml
183+
certification_report*.yaml
179184
quality_report*.json
185+
slop_*.json
186+
slop_report*.json
187+
188+
# Scratch / test artefacts
189+
test_doc.txt
190+
191+
# CR-EP internal config
192+
.cr-ep/

CHANGELOG.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,104 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
---
99

10+
## [1.6.1] - 2026-04-19
11+
12+
### Refactored
13+
14+
- **API orchestration** (`api.py`): `initialize_services` (66 lines, CC~8) →
15+
`_init_searcher` + `_init_cache` + `_init_metrics` + 8-line orchestrator.
16+
`_record_upload_failure` extracted — eliminates 2× duplicated
17+
`record_file_upload + record_error` blocks in `upload_single_file`.
18+
19+
- **Admin auth** (`admin_routes.py`): `_get_admin_user` (77 lines, CC~10) →
20+
`_parse_bearer_token` + `_try_oauth_admin` + `_resolve_key_admin` + 5-line
21+
orchestrator. Fixes `reverse_field_glyphs` rebuilt on every recursive call.
22+
23+
- **Engine** (`engine/chronos_grid.py`): `seek_vector_resonance` (80 lines,
24+
2 code paths) → `_hnsw_vector_resonance` + `_brute_vector_resonance` +
25+
10-line dispatcher (HNSW path vs brute-force cosine similarity).
26+
27+
- **Engine** (`engine/gravitas_pack.py`): `_compress_dict` / `_decompress_dict`
28+
clone cluster → `_transform_dict(obj, key_map, value_transform)` dispatch table.
29+
Both callers become 2-line delegators.
30+
31+
### Changed
32+
33+
- **`eval_self.py`**: `CORPUS_FILES` split into `AUDIT_CORPUS` (11 docs) +
34+
`SOURCE_CORPUS` (7 source files). `CORPUS_FILES = AUDIT_CORPUS + SOURCE_CORPUS`
35+
preserves existing full-pack behaviour; `AUDIT_CORPUS` alone enables lightweight
36+
doc-quality runs.
37+
38+
- **`.gitignore`**: `docs/history/` added under "Historical development artifacts".
39+
40+
### Tests
41+
42+
- 475 passed, 13 skipped — same count as v1.6.0 (1 pre-existing flaky timing test
43+
in full suite; passes in isolation).
44+
45+
---
46+
47+
## [1.6.0] - 2026-04-19
48+
49+
### Added
50+
51+
- **BM25 + RRF Hybrid Search** (`engine/hybrid_search.py`): Production-grade BM25
52+
(k1=1.5, b=0.75) with Korean+English tokenizer
53+
(`re.findall(r"[a-z0-9\uac00-\ud7a3]+", text.lower())`).
54+
Reciprocal Rank Fusion merges BM25 and ChronosGrid semantic lists using
55+
string URI as doc ID — no integer alignment required. k=60, top_k configurable.
56+
Lazy per-store index with `_bm25_dirty` set: index rebuilt on first hybrid
57+
search after any upload, not on every upload.
58+
59+
- **KnowledgeAtom chunk-level indexing** (`engine/knowledge_atom.py`): Two-level
60+
indexing — file-level doc + chunk atoms with fragment URIs
61+
(`local://store/enc_path#c0001`). `chunk_and_inject()` splits content into
62+
800-char overlapping windows (120-char overlap, 80-char minimum), embeds each
63+
chunk via `embedding_generator.generate()`, injects into ChronosGrid, and
64+
registers in `_atom_store_docs` for URI-based resolution. Enables precision
65+
chunk-level retrieval alongside file-level documents.
66+
67+
- **Stable URI scheme**: Local documents now use
68+
`local://<store>/<urllib.parse.quote(abs_path, safe='')>` instead of
69+
`local://<store>/<basename>`. Eliminates collisions when files with identical
70+
names exist in different directories. URIs are reversible via `unquote()`.
71+
Both main docs and chunk atoms share the same URI namespace.
72+
73+
### Refactored
74+
75+
- **`core.py` segmentation** (1258 → 221 lines): `FlamehavenFileSearch` split into
76+
three focused mixin classes via `IngestMixin`, `LocalSearchMixin`,
77+
`CloudSearchMixin`. `core.py` is now a thin orchestrator: `__init__`,
78+
`create_store`, `list_stores`, `delete_store`, `get_metrics`,
79+
`_resolve_vector_backend`.
80+
81+
| Mixin | File | Responsibility |
82+
|---|---|---|
83+
| `IngestMixin` | `_ingest.py` (228 L) | upload_file, upload_files, _local_upload, _generate_file_vector |
84+
| `LocalSearchMixin` | `_search_local.py` (273 L) | _local_search, BM25 rebuild, hybrid rerank, RAG prompt |
85+
| `CloudSearchMixin` | `_search_cloud.py` (265 L) | search, search_stream, search_multimodal + 6 shared helpers |
86+
87+
- **Duplicate helper elimination** (`_search_cloud.py`): Six blocks that were
88+
copy-pasted between `search()` and `search_multimodal()` are now shared helpers:
89+
`_resolve_search_params`, `_ensure_store`, `_query_vector_backend`,
90+
`_driftlock_validate`, `_extract_grounding_sources`, `_gemini_search_call`.
91+
92+
### Fixed
93+
94+
- **`search_stream` double intent-refine bug**: `intent_refiner.refine_intent(query)`
95+
was called twice (lines 984 and 988 in old `core.py`) — once before the
96+
provider-RAG branch and once inside it. The second call discarded the first
97+
`optimized_query`. Fixed: single call, result reused throughout the method.
98+
99+
### Tests
100+
101+
- 443 tests pass, 13 skipped — no regression from refactor.
102+
- `test_flamehaven_remote_client_flow` patch target updated: also patches
103+
`flamehaven_filesearch._search_cloud._google_genai_types` after types moved
104+
from `core.py` to `_search_cloud.py`.
105+
106+
---
107+
10108
## [1.5.3] - 2026-04-19
11109

12110
### Added

README.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
### Self-hosted RAG search engine. Production-ready in 3 minutes.
88

99
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10-
[![Version](https://img.shields.io/badge/version-1.5.3-blue.svg)](CHANGELOG.md)
10+
[![Version](https://img.shields.io/badge/version-1.6.1-blue.svg)](CHANGELOG.md)
1111
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/)
1212
[![Docker](https://img.shields.io/badge/docker-ready-brightgreen.svg)](https://hub.docker.com/r/flamehaven/filesearch)
1313

@@ -17,13 +17,13 @@
1717

1818
---
1919

20-
## 🎯 Why FLAMEHAVEN?
20+
## 🎯 Why FLAMEHAVEN FileSearch?
2121

22-
Stop sending your sensitive documents to third-party services. Get enterprise-grade semantic search running locally in minutes, not days.
22+
Stop sending your sensitive documents to third-party services. FLAMEHAVEN FileSearch is a production-grade RAG search engine — BM25+hybrid retrieval, 34 file formats, multi-LLM (Gemini, OpenAI, Claude, Ollama) — running self-hosted in minutes, not days.
2323

2424
```bash
2525
# One command. Three minutes. Done.
26-
docker run -d -p 8000:8000 -e GEMINI_API_KEY="your_key" flamehaven-filesearch:1.5.2
26+
docker run -d -p 8000:8000 -e GEMINI_API_KEY="your_key" flamehaven-filesearch:1.6.1
2727
```
2828

2929
<table>
@@ -57,9 +57,9 @@ Open source & MIT licensed</p>
5757

5858
| Capability | Detail |
5959
|---|---|
60-
| **Search Modes** | Keyword, semantic, and hybrid with automatic typo correction |
60+
| **Search Modes** | Keyword, semantic, and hybrid (BM25+RRF) with automatic typo correction |
6161
| **34 File Formats** | PDF, DOCX/DOC, XLSX, PPTX, RTF, HTML, CSV, LaTeX, WebVTT, images + plain text — see [Document Parsing](docs/wiki/Document_Parsing.md) |
62-
| **RAG Pipeline** | Structure-aware chunking, sliding-window context enrichment, mtime parse cache |
62+
| **RAG Pipeline** | Structure-aware chunking, KnowledgeAtom 2-level indexing, sliding-window context enrichment, mtime parse cache |
6363
| **Ultra-Fast Vectors** | DSP v2.0 generates embeddings in <1ms — no ML frameworks required |
6464
| **Source Attribution** | Every answer links back to the originating document and chunk |
6565
| **Framework SDKs** | LangChain, LlamaIndex, Haystack, CrewAI adapters out of the box |
@@ -83,7 +83,7 @@ docker run -d \
8383
-e GEMINI_API_KEY="your_gemini_api_key" \
8484
-e FLAMEHAVEN_ADMIN_KEY="secure_admin_password" \
8585
-v $(pwd)/data:/app/data \
86-
flamehaven-filesearch:1.5.2
86+
flamehaven-filesearch:1.6.1
8787
```
8888

8989
✅ Server running at `http://localhost:8000`
@@ -167,7 +167,7 @@ pip install flamehaven-filesearch[all]
167167
# Build from source
168168
git clone https://github.com/flamehaven01/Flamehaven-Filesearch.git
169169
cd Flamehaven-Filesearch
170-
docker build -t flamehaven-filesearch:1.5.2 .
170+
docker build -t flamehaven-filesearch:1.6.1 .
171171
```
172172

173173
### Framework Integrations
@@ -259,7 +259,7 @@ security:
259259
</tr>
260260
<tr>
261261
<td>Test Suite</td>
262-
<td><code>443 tests</code></td>
262+
<td><code>476 tests</code></td>
263263
<td>All passing (pytest)</td>
264264
</tr>
265265
<tr>
@@ -299,8 +299,9 @@ flowchart TD
299299
subgraph Engine["Engine Layer"]
300300
FP["FileParser\n+ BackendRegistry\n(34 formats)"]
301301
Cache["ParseCache\n(mtime-based)"]
302-
Chunker["TextChunker\n+ ContextExtractor"]
302+
Chunker["TextChunker\n+ KnowledgeAtom\n(chunk atoms)"]
303303
DSP["DSP v2.0\nEmbedding Generator\n(&lt;1ms, zero-ML)"]
304+
BM25["BM25 + RRF\nHybrid Search\n(v1.6.0)"]
304305
Scorer["SemanticScorer\n+ TypoCorrector"]
305306
end
306307

@@ -383,7 +384,14 @@ Full roadmap: [ROADMAP.md](ROADMAP.md)
383384
- [x] Backend Plugin Architecture — `AbstractFormatBackend` + `BackendRegistry` (v1.5.2)
384385
- [x] Parse cache — mtime-based, `extract_text(use_cache=True)` (v1.5.2)
385386
- [x] ContextExtractor — sliding-window RAG chunk enrichment (v1.5.2)
386-
- [x] 443 tests; AI-Slop-Detector critical deficits: 0 (v1.5.2)
387+
- [x] Multi-provider LLM support — OpenAI, Claude, Ollama, Gemini (v1.5.3)
388+
389+
### v1.6.0 (Completed)
390+
- [x] BM25 + RRF hybrid search — Korean+English tokenizer, lazy per-store index
391+
- [x] KnowledgeAtom 2-level indexing — chunk atoms with fragment URIs
392+
- [x] Stable URI scheme — `local://<store>/<quote(abs_path)>`, collision-free
393+
- [x] core.py mixin segmentation — 1258 → 221 lines, 3 focused modules
394+
- [x] Fix: `search_stream` double intent-refine bug
387395

388396
### v2.0.0 (Q3 2026)
389397
- [ ] Multi-language support (15+ languages) — multilingual stopwords + jieba
@@ -465,9 +473,10 @@ Use the links below to jump to the most relevant guide.
465473
| Topic | Description |
466474
|-------|-------------|
467475
| [Document Parsing](docs/wiki/Document_Parsing.md) | Supported formats, internal parsers, RAG chunking |
476+
| [Hybrid Search](docs/wiki/Hybrid_Search.md) | BM25+RRF, KnowledgeAtom indexing, stable URI scheme (v1.6.0) |
468477
| [Framework Integrations](docs/wiki/Framework_Integrations.md) | LangChain, LlamaIndex, Haystack, CrewAI adapters |
469478
| [API Reference](docs/wiki/API_Reference.md) | REST endpoints, payloads, rate limits |
470-
| [Architecture](docs/wiki/Architecture.md) | How all layers fit together (v1.5.2) |
479+
| [Architecture](docs/wiki/Architecture.md) | How all layers fit together (v1.6.0) |
471480
| [Configuration Reference](docs/wiki/Configuration.md) | Full list of environment variables and config fields |
472481
| [Production Deployment](docs/wiki/Production_Deployment.md) | Docker, systemd, reverse proxy, scaling tips |
473482
| [Troubleshooting](docs/wiki/Troubleshooting.md) | Step-by-step debugging playbook |
@@ -536,6 +545,6 @@ Built with amazing open source tools:
536545

537546
Built with 🔥 by the Flamehaven Core Team
538547

539-
*Last updated: April 19, 2026 • Version 1.5.3*
548+
*Last updated: April 19, 2026 • Version 1.6.1*
540549

541550
</div>

ROADMAP.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ This roadmap reflects the current constraints and priorities for Flamehaven
44
FileSearch. Weekly usage budget is ~2%, so immediate focus is cost and quota
55
pressure reduction before expanding surface area.
66

7+
## v1.6.0 (Released: 2026-04-19)
8+
9+
**Focus:** Native RAG architecture — BM25+RRF hybrid search, chunk-level indexing.
10+
11+
- [x] BM25 engine — Korean+English tokenizer, k1=1.5, b=0.75, lazy per-store rebuild.
12+
- [x] RRF fusion (k=60) — merges BM25 and ChronosGrid semantic lists by URI.
13+
- [x] KnowledgeAtom 2-level indexing — chunk atoms with `#cNNNN` fragment URIs.
14+
- [x] Stable URI scheme — `local://<store>/<quote(abs_path)>`, collision-free.
15+
- [x] core.py mixin segmentation — 1258 → 221 lines; 3 focused mixin modules.
16+
- [x] Fix: `search_stream` double intent-refine bug.
17+
- [x] 443 tests pass, 13 skipped; AI-Slop-Detector: CLEAN.
18+
719
## Next Steps (Now)
820

921
- [ ] Cache + cost improvements (cache hit tracking by search mode/backend,

docs/wiki/Architecture.md

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Architecture Overview
22

33
Flamehaven FileSearch balances simplicity with production-grade safeguards. This
4-
document describes the moving parts as of **v1.5.2**, featuring:
4+
document describes the moving parts as of **v1.6.0**, featuring:
55
- **Gravitas DSP Engine** (v1.3.1+)
66
- **Multimodal Search** (v1.4.0+)
77
- **pgvector with HNSW** (v1.4.0+)
@@ -10,6 +10,8 @@ document describes the moving parts as of **v1.5.2**, featuring:
1010
- **Universal Document Parser, Internal Chunker, Framework Integrations** (v1.5.0)
1111
- **Dead code removal, critical complexity fixes, 360-test suite** (v1.5.1)
1212
- **Parse Cache, ContextExtractor, Backend Plugin Architecture** (v1.5.2)
13+
- **Multi-provider LLM support** (v1.5.3)
14+
- **BM25+RRF Hybrid Search, KnowledgeAtom, Mixin Architecture** (v1.6.0)
1315

1416
---
1517

@@ -42,13 +44,73 @@ Request → │ FastAPI Router│ ─────> │ Middleware │ ──┐
4244

4345
---
4446

45-
## 2. Core Search Engine (v1.4.1)
47+
## 2. Core Architecture (v1.6.0 — Mixin Pattern)
4648

47-
`FlamehavenFileSearch` (in `core.py`) now supports three primary search modes:
49+
`FlamehavenFileSearch` is now a thin orchestrator composed of three focused mixins:
4850

49-
- **Keyword Mode** – Traditional exact match indexing.
50-
- **Semantic Mode (OMEGA)** – Powered by the **Gravitas DSP Engine**. Uses Deterministic Semantic Projection (v2.0) to map text into a 384-dimensional space without heavy ML dependencies.
51-
- **Hybrid Mode** – Combines both keyword and semantic scores for maximum precision.
51+
```
52+
core.py (221 lines)
53+
FlamehavenFileSearch(IngestMixin, LocalSearchMixin, CloudSearchMixin)
54+
__init__ / create_store / list_stores / delete_store / get_metrics
55+
56+
_ingest.py (228 lines) — IngestMixin
57+
upload_file / upload_files / _local_upload / _generate_file_vector
58+
59+
_search_local.py (273 lines) — LocalSearchMixin
60+
_local_search / _run_hybrid_rerank / _rebuild_bm25
61+
_get_doc_by_uri / _build_snippet / _build_rag_prompt / _provider_search
62+
63+
_search_cloud.py (265 lines) — CloudSearchMixin
64+
search / search_stream / search_multimodal
65+
+ shared helpers: _resolve_search_params / _ensure_store /
66+
_query_vector_backend / _driftlock_validate /
67+
_extract_grounding_sources / _gemini_search_call
68+
```
69+
70+
`FlamehavenFileSearch` supports three primary search modes:
71+
72+
- **Keyword Mode** – BM25-scored exact match indexing across all stored content.
73+
- **Semantic Mode (OMEGA)** – Powered by the **Gravitas DSP Engine**. Uses
74+
Deterministic Semantic Projection (v2.0) to map text into a 384-dimensional
75+
space without heavy ML dependencies.
76+
- **Hybrid Mode** – BM25 + ChronosGrid semantic merged via Reciprocal Rank
77+
Fusion (RRF, k=60). See [Section 2a](#2a-bm25--rrf-hybrid-search) below.
78+
79+
### 2a. BM25 + RRF Hybrid Search
80+
81+
**Implementation:** `engine/hybrid_search.py`
82+
83+
```
84+
BM25 (k1=1.5, b=0.75)
85+
tokenizer: re.findall(r"[a-z0-9\uac00-\ud7a3]+", text.lower())
86+
Korean Hangul syllable range: \uac00-\ud7a3
87+
Lazy index per store — rebuilt only after uploads (_bm25_dirty flag)
88+
Corpus: main docs + chunk atoms (full 2-level coverage)
89+
90+
RRF(d) = sum(1 / (k + rank_i)) k=60, rank from each result list
91+
92+
Fusion inputs:
93+
List A: ChronosGrid semantic results (similarity-ranked)
94+
List B: BM25 scored results (BM25 score-ranked)
95+
ID key: stable URI string (collision-free across lists)
96+
97+
Output: top-k docs resolved via _get_doc_by_uri()
98+
```
99+
100+
### 2b. KnowledgeAtom 2-Level Indexing
101+
102+
**Implementation:** `engine/knowledge_atom.py`
103+
104+
Level 1 — File doc: `local://<store>/<quote(abs_path)>`
105+
Level 2 — Chunk atoms: `local://<store>/<quote(abs_path)>#c0001`
106+
107+
`chunk_and_inject()`:
108+
- Splits content into 800-char windows with 120-char overlap
109+
- Skips chunks shorter than 80 chars (noise filter)
110+
- Embeds each chunk via `embedding_generator.generate()`
111+
- Injects into ChronosGrid for semantic retrieval
112+
- Registers in `_atom_store_docs[store_name][atom_uri]` for URI lookup
113+
- Both levels participate in BM25 corpus via `_rebuild_bm25()`
52114

53115
### Gravitas DSP Engine (v2.0)
54116
- **Zero-Dependency Vectorizer**: Replaced `sentence-transformers` with a lightweight, signed feature hashing algorithm.
@@ -84,9 +146,9 @@ The new **Chronos-Grid** integration handles high-speed vector storage and simil
84146

85147
---
86148

87-
## 6. Testing & Quality (v1.4.2)
149+
## 6. Testing & Quality (v1.6.0)
88150

89-
- **Test Framework**: `pytest` — 443 tests collected, all passing (360 + 83 new).
151+
- **Test Framework**: `pytest` — 443 tests pass, 13 skipped.
90152
- **Lint**: `black` (format) + `ruff` (lint/unused imports) — both enforced in CI.
91153
- **Validation**: `validators.py` enforces security policies (Filename 200-char max, FileSize, SearchQuery XSS/SQLi checks).
92154
- **SIDRCE Certification**: Omega 0.9894 (S++) — AI-Slop-Detector P0-P5 clean.
@@ -125,6 +187,8 @@ engine/
125187
parse_cache.py — mtime-based parse result cache (v1.5.2)
126188
context_extractor.py — RAG chunk context window extractor (v1.5.2)
127189
text_chunker.py — Structure-aware + token-aware RAG chunker (stdlib only)
190+
hybrid_search.py — BM25 + RRF fusion engine (v1.6.0)
191+
knowledge_atom.py — Chunk-level atom indexing with fragment URIs (v1.6.0)
128192
embedding_generator.py — DSP v2.0 vectorizer
129193
chronos_grid.py — Vector index + metadata store
130194
gravitas_pack.py — Metadata compression

0 commit comments

Comments
 (0)