Skip to content

Releases: ssmurfgg04-gif/context-m

v0.6.0 — IR audit full implementation

Choose a tag to compare

@ssmurfgg04-gif ssmurfgg04-gif released this 29 Aug 13:59

What shipped in 0.6.0 — full IR audit implementation

Implements EVERY item from the user's Aug-2026 IR audit (12 Lucene/Solr primitives + 5 Google-style query-time fixes + SQLite PRAGMA tuning + parallel benchmark runner).

New modules (cortexm/bridge/)

  • synonyms.py — Lucene synonym_graph filter ported to μ=0. 8 curated concept clusters (employment, residence, pet_name, education, vehicle, preference, negation, family). Phrase-level substitution via master regex (longest-first sort). Default max_expansions=16. Runtime-extensible via register_cluster().
  • recognizers.py — Microsoft Recognizers-Text style deterministic entity resolution. 40+ holidays with algorithmic resolution (Thanksgiving = 4th Thursday of November via _nth_weekday; Easter = Gauss's computus; MLK = 3rd Monday of January; Memorial Day = last Monday of May). Currency extraction (USD/EUR/GBP/JPY/CNY/INR with both $/€/£ symbols and "dollars"/"euros"/"pounds" word forms).
  • fst.py — Lightweight FST for query normalization. 60+ abbreviation expansions (UCLA → University of California Los Angeles, MIT → Massachusetts Institute of Technology, NYC → New York City) + 25+ common misspellings (recieve → receive, teh → the). Idempotent. Case-preserving.
  • slang.py — Curated slang normalization dictionary (80+ entries). bruh → "", deadass → seriously, no cap → truthfully, finna → going to, gonna → going to, y'all → you all. Multi-word-phrase aware ("no cap" is one semantic unit).
  • negation.py — Negation detection + indexing as metadata (not as positive fact). 30+ negation markers (don't, do not, never, no longer, stopped, quit). Sentence-level detection. extract_with_negation() splits text into positive_text + negations. SQL schema for negation_records table.
  • multilingual.py — Language detection + per-language routing via Unicode script analysis (no model needed). Detects en/zh/ja/ko/ar/hi/ru/th. Conservative 30% threshold. segment_by_language() splits code-switched text into language-homogeneous segments.
  • query_rewrite.py — Orchestrator running 4 stages in order: slang → FST → synonyms → recognizers. Returns list of expanded queries (original always first). Holiday partial-match bug fixed via negative-lookahead regex + consumed_spans tracking.
  • ir_pro.py — All 12 IR primitives the audit flagged, consolidated in one module:
    • 6-stage analyze() pipeline: NFKC → lowercase → tokenize → stopword removal → stem
    • 165-word English stopword set + 6-language stopword lists (en/es/fr/de/it/pt)
    • nfkc_normalize() (fi → fi, ² → 2)
    • strip_accents() (Café → Cafe)
    • stem() lightweight Porter-like stemmer (running → runn, dogs → dog, cities → city)
    • build_phrase_query() (slop=0 → "phrase"; slop=2 → NEAR(a, b, 2))
    • phrase_search() (FTS5 NEAR())
    • highlight() (FTS5 snippet() with custom before/after markers)
    • facet_counts() (GROUP BY on facts table — relation/subject/value)
    • more_like_this() (term-vector similarity via FTS5 fts5vocab)
    • range_search() (numeric range via CAST(value AS REAL) B-tree scan)
    • suggest() (fts5vocab prefix search)
    • correct_spelling() (full-string Levenshtein DP — NOT Bitap which does substring matching)
    • correct_query() (per-token spell correction)
    • LRUCache with per-user invalidation
    • optimize_index() (VACUUM + FTS5 'optimize' + wal_checkpoint)

VerbatimPlugin extensions

  • search() now wraps _search_single() (the original v0.5.3 path) with the QueryRewriter — ADDITIVE (runs original + expansions through BM25, unions by rowid, can only surface MORE hits never fewer — protects existing 0.948 canonical score)
  • LRU query cache (capacity 1024) with per-user invalidation on add()
  • 11 new public methods: phrase_search, highlight, facet_counts, more_like_this, range_search, suggest, correct_spelling, correct_query, optimize_index, tune_bm25, invalidate_cache

TraceStore PRAGMA tuning

TraceStore.__init__ now takes 5 new kwargs: pragma_cache_mb (64MB default), pragma_mmap_mb (256MB), pragma_threads (4), pragma_temp_in_memory (True), pragma_locking_exclusive (False, opt-in). Memory class passes Config values through. Google-style read-heavy optimization.

Config

16 new Config fields, all default ON (additive — can only help, never hurt): query_rewrite_enabled, slang_normalization_enabled, abbreviation_expansion_enabled, spelling_correction_enabled, synonym_expansion_enabled, holiday_resolution_enabled, query_max_expansions (8), negation_indexing_enabled, multilingual_routing_enabled, query_cache_enabled, query_cache_capacity (1024), bm25_k1 (1.5), bm25_b (0.75), index_optimize_on_consolidate, highlight_tokens (10), suggest_min_count (2), pragma_cache_mb (64), pragma_mmap_mb (256), pragma_threads (4), pragma_temp_in_memory (True).

Parallel benchmark runner

scripts/longmemeval_canonical_parallel.pymultiprocessing.Pool (spawn context to avoid fork-safety issues). Each worker opens its own READ-ONLY SQLite connection (WAL allows concurrent readers). Expected 4× speedup on 4-core machine. Mirrors the sequential runner's arg parser so callers can swap transparently.

Tests

tests/test_v060_ir_pro.py — 109 new tests covering every new module + every new VerbatimPlugin method + Config new flags + PRAGMA tuning + μ=0 invariant upheld.

Full regression: 626 passed (was 517; +109), 24 skipped, 0 failures in 21s.

μ=0 invariant upheld

Verified via test_memory_add_does_not_increment_llm_calls: Memory.add + Memory.search does NOT bump the LLM_CALLS counter. All new modules are pure Python (regex + dict + DP), no LLM, no API, no statistics beyond IDF/BM25.

Bugs found + fixed during testing

  • recognizers.py had invalid Python syntax (walrus operator inside dict literal) → fixed
  • query_rewrite.py had a partial-match bug ("valentine" inside "valentine's day" produced "2026-02-14's Day") → fixed via negative-lookahead regex
  • ir_pro.stem() had regex rules that captured only ONE letter (so "running" → "n") → rewrote with re.subn using (.+) captures
  • ir_pro.correct_spelling() was using Bitap (which does SUBSTRING matching — "dogg" vs "dog" returned 0) → switched to full-string Levenshtein DP
  • multilingual.py segment_by_language() mislabeled "私は" (Hiragana) as "zh" because the first char "私" is CJK → rewrote to scan ALL chars in a token
  • multilingual.py detect_language() 20% threshold was too aggressive ("I love 東京" mislabeled as "zh") → bumped to 30%

Live on PyPI

pip install cortexmhttps://pypi.org/project/cortexm/0.6.0/

Trusted-publish via .github/workflows/release.yml (OIDC, no API token). Workflow run: https://github.com/ssmurfgg04-gif/context-m/actions/runs/33256284241

Promises intact

✅ Always remembers · ✅ Flat cost μ=0 · ✅ Own your data · ✅ Doesn't lie · ✅ Same every time

No LLM embedder swap (HashingEmbedder stays per user instruction).

v0.5.7 — README trim + .gitattributes + PyPI publish

Choose a tag to compare

@ssmurfgg04-gif ssmurfgg04-gif released this 29 Aug 10:18

What shipped in 0.5.7

Based on a research sweep of the top 1% fastest-growing GitHub AI/infra repos (chroma · mem0 · llama_index · langchain · zep · aider · shadcn/ui · supabase · ollama · vllm · litellm · instructor · smolagents · letta · open-webui · mcp-servers · continuedev) and HN/Reddit launch patterns.

Repo polish

  • .gitattributes*.html linguist-generated=true removes the trajectory viewer / leaderboard HTML from GitHub's language bar (was inflating "90% HTML" because Linguist counts lines, not files).
  • README.md 742 → 100 lines (85% reduction) — new top fold mirrors Mem0/Aider/Chroma shape: centered title + 6 essential badges + 1-line blockquote hook + 1-paragraph differentiator + 5-line Quick Start + 2-column LongMemEval table + "When to use cortexm vs Mem0/Zep/Chroma" + drop-in plugins list + docs link table.
  • pyproject.toml PEP 639 compliant — SPDX license = "Apache-2.0" (no deprecated {file = "LICENSE"} form), readme.content-type = "text/markdown" (was bare; would have rendered as plain text on PyPI), 11 classifiers, 21 high-search-volume keywords (agent-memory / llm-memory / long-term-memory / mem0 / memgpt / letta / zep / chroma / deterministic-ai / local-first / vector-symbolic-architecture / provenance / bi-temporal / hippocampus / context-engineering / rag / mcp / self-hosted), 5 project URLs (Documentation / Repository / Issues / Changelog).
  • Topics + About + Discussions enabled — 18 GitHub topics for topic-page discovery, description set to the tagline, Discussions on for "how-do-I" questions (mem0/langchain/supabase all do this).

Code-quality state (verified, no changes needed)

  • cortexm/__init__.py exposes Memory, Config, Pipeline, Context, mount_default, LLM_CALLS. Memory class has add, edit, fix, recall_step, preload_context, export_markdown, import_markdown, search, apply_rules, consolidate, close (idempotent).
  • cortexm/config.py defaults: verbatim_ingest_enabled=True, verbatim_search_enabled=True, recall_step_in_search=True — the 0.948 canonical score depends on all three being ON; guarded by tests/test_public_api_smoke.py::test_config_defaults_ensure_verbatim.
  • cortexm/text/embedder.py: HashingEmbedder has PolyglotEncoder fallback for non-English text (CJK/Devanagari/Arabic/Cyrillic/Thai/Hangul/Kana) via the labse_enabled opt-in flag.
  • scripts/longmemeval_canonical_full.py (620 lines) is in the repo — the 500-question canonical run workflow.
  • plugins/dsh-cortexm/package.json version 1.0.0 — independent npm versioning (matches what's published on npm).

Tests + build

  • 517 tests pass, 24 skipped, 0 failures in 21s (regression suite).
  • Wheel cortexm-0.5.7-py3-none-any.whl (438 KB) + sdist (477 KB) build clean.
  • Smoke test on built wheel: import cortexm__version__ == '0.5.7'LLM_CALLS == 0Memory().add() + Memory().search() roundtrip works.

Live on PyPI

pip install cortexmhttps://pypi.org/project/cortexm/0.5.7/

Trusted-publish via .github/workflows/release.yml (OIDC, no API token). Workflow run: https://github.com/ssmurfgg04-gif/context-m/actions/runs/33247162186

Promises intact

✅ Always remembers · ✅ Flat cost μ=0 · ✅ Own your data · ✅ Doesn't lie · ✅ Same every time

No LLM embedder swap (HashingEmbedder stays per user instruction).