Skip to content

[integration] v1.4.5 — bug fixes, dead code removal, lifespan refactor#6

Open
Atrv-Shrn wants to merge 18 commits into
mainfrom
feat/integration
Open

[integration] v1.4.5 — bug fixes, dead code removal, lifespan refactor#6
Atrv-Shrn wants to merge 18 commits into
mainfrom
feat/integration

Conversation

@Atrv-Shrn
Copy link
Copy Markdown
Owner

Summary

  • BUG-1: Changed env_file_encoding from "utf-8" to "utf-8-sig".env files saved with a UTF-8 BOM no longer cause MEMSTACK_VAULT_PATH validation errors
  • ISSUE-1: Removed unused obsidian_mode config field from Settings, .env.example, and all test fixtures — the field was declared but never read by any code path
  • ISSUE-2: Replaced 6 hardcoded version string assertions with __version__ import — tests no longer break on version bumps
  • ISSUE-3: Moved watcher/consolidator startup/shutdown from deprecated @app.on_event to _app_lifespan async context manager
  • Bumped version from 1.4.4 to 1.4.5
  • Regenerated README.md as a self-contained user guide with glossary, all-platform instructions, full API reference, e2e walkthrough, and troubleshooting

Merged PRs

# Branch Status
4 feat/config-fixes Squash-merged
3 feat/version-assertions Squash-merged
5 feat/lifespan-refactor Manual merge (CHANGELOG conflict resolved)

Changes

  • src/memstack/core/config.pyutf-8-sig encoding, removed obsidian_mode
  • src/memstack/interfaces/rest/app.py — lifespan refactor, removed 4 @app.on_event handlers
  • tests/test_config.py — 2 new BOM tests, removed obsidian_mode assertions
  • tests/test_routes_health.py__version__ assertions, renamed test method
  • tests/test_mcp_server.py__version__ assertions, renamed test method
  • tests/test_cli.py__version__ assertion
  • tests/test_app.py — lifespan test update
  • tests/test_vault.py, tests/test_watcher.py — removed obsidian_mode from fixtures
  • .env.example — removed MEMSTACK_OBSIDIAN_MODE, version header → 1.4.5
  • __init__.py, pyproject.toml — version → 1.4.5
  • README.md — full rewrite as self-contained user guide
  • CHANGELOG.md — v1.4.5 section
  • ARCHITECTURE.md, CONTRIBUTING.md — updated (gitignored, on disk)
  • STATUS.md, progress.md — updated with integration status

Acceptance criteria verified

  • 593 tests pass
  • ruff check src/ tests/ clean, ruff format --check src/ tests/ clean
  • git grep on_event -- src/ → zero
  • git grep obsidian_mode -- src/ tests/ → zero
  • git grep '"1\.4\.[0-3]"' -- tests/ → zero
  • Version 1.4.5 consistent across all files

Known limitations

  • No size limit on auto-capture content (removing slice(-4) is the fix; adding a configurable window is a feature)
  • Ollama singleton ignores host parameter after first creation
  • Background task reference not stored for graceful await on shutdown
  • Merge operation not atomic: if a delete fails after new memory is written, both may exist
  • LLM response IDs validated only by existence check

🤖 Generated with Claude Code

Atrv-Shrn and others added 18 commits May 14, 2026 18:07
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…o lifespan

Move watcher and consolidator startup/shutdown from deprecated
@app.on_event("startup"/"shutdown") handlers into the existing
_app_lifespan async context manager with try/finally.

Also replace 6 hardcoded version string assertions with __version__
import and rename 2 stale test methods.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
#4)

- Change env_file_encoding from "utf-8" to "utf-8-sig" so .env files
  with a UTF-8 BOM are parsed correctly (vault_path no longer gets
  BOM prefix)
- Remove dead obsidian_mode field from Settings class, .env.example,
  and all test fixtures (never read by any code path)
- Add BOM-stripping and BOM-free regression tests
- Update CHANGELOG with v1.4.5 section

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…#3)

6 hardcoded "1.4.3" assertions replaced with __version__ from memstack.
Renamed test_health_version_is_1_4_2 → test_health_version_matches_package
and test_mcp_server_version_is_1_4_2 → test_mcp_server_version_matches_package.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…efactor PR

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Bump version from 1.4.4 to 1.4.5 in __init__.py, pyproject.toml, .env.example
- Add v1.4.5 changelog entry to README.md
- Update health example version string in README.md
- Update STATUS.md and progress.md with integration status
- Fix ruff format in index.py, test_async_execution.py

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- README.md: complete rewrite as self-contained user guide with glossary,
  all-platform instructions, full API reference, e2e walkthrough,
  troubleshooting with exact fix commands, known warnings
- STATUS.md: update with /finish status and v1.4.5 verification
- progress.md: append /start-int and /finish entries
- uv.lock: version bump from 1.4.4 to 1.4.5

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Updated .gitignore to track dev files on feat/integration:
- reference/ docs, CLAUDE.md, CONTEXT.md, STATUS.md, progress.md
- ARCHITECTURE.md, CONTRIBUTING.md, .claude/ specs and settings
- tests/test_consolidation.py, tests/test_synthesis.py

Updated branch-plan.md for v1.4.5 reactive summit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ng model change

Adds SearchIndex.validate_dimension() that checks if existing LanceDB
vector dimensions match the current embedding provider. On mismatch,
logs a warning and triggers a full reindex from vault. Skips gracefully
when no table exists or no provider is configured.

Called at startup in both REST app and MCP server lifespan, before
vault scan. 5 tests covering no-table, matching, mismatch, no-provider,
and embed-failure cases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove embedding_autofallback config field and silent fallback logic.
Default embedding provider changed from ollama to fastembed, default
model changed from nomic-embed-text to BAAI/bge-small-en-v1.5.
When the configured provider is unavailable, raise RuntimeError
immediately instead of silently falling back.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Combined continuity docs after merging feat/dimension-validation into
feat/integration alongside feat/embedding-config.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix stale embedding defaults and AUTOFALLBACK references in README.md
- Remove autofallback mentions from ARCHITECTURE.md
- Add v1.4.5 entries for embedding-config and dimension-validation in CHANGELOG.md
- Update STATUS.md and progress.md with merged PR status and verification results

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…milarity_ignore_enabled

LLM responses wrapped in ```json``` code fences caused json.loads() to fail,
silently falling back to wrong behavior: duplicates in smart write (add instead
of merge), skipped extraction in synthesis, and skipped batches in consolidation.
Strip fences before parsing in llm.py, synthesis.py, and consolidation.py.

The similarity_ignore_enabled flag bypassed LLM consultation for high-similarity
matches, discarding genuinely new information. Removed the flag and the early-return
block so the LLM always decides between add/merge/update/ignore. The reference
architecture requires LLM consultation for all scores at or above the add threshold.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…egory classification to pipeline

Pagination:
- Add limit/offset params to VaultStore.list_memories(), REST GET /memories, MCP memory_list
- Add MemoryListResponse model with memories, total, limit, offset fields
- Default limit=50; limit=0 returns all (used by consolidator)
- Update cache key from str to (agent_id, limit, offset) tuple

Category classification:
- New intelligence/classify.py with classify_content() calling LLM for categorisation
- 10 categories: food, fitness, work, entertainment, tools, relationships, health, travel, education, other
- Pipeline auto-tags every memory with cat:{category} via classify_content()
- New SearchIndex.find_by_tag() for tag-based memory lookup
- Same-category memories injected into LLM consultation as merge candidates
- consult_llm() now accepts incoming_category parameter

Bug fixes (from bug report analysis):
- Watcher _handle_add_or_update() now always deletes old index entries before re-indexing
- scan_vault() now cleans up orphaned index entries for deleted vault files
- New SearchIndex.list_memory_ids() for orphan cleanup
- LLM consultation prompt improved for categorical grouping and contradiction handling
- LLM consultation now produces merged_content for coherent merge rewrites
- VaultStore.merge() accepts optional merged_body for LLM-rewritten content
- Synthesis prompt updated to preserve specifics that pin down preferences

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The prompt asked for a bare category name but format="json" forces
Ollama to produce JSON. This mismatch caused json.loads() to crash on
non-JSON output, silently falling back to "other" for every memory.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…owing

The agent_end handler's empty catch block made connection failures and
HTTP errors completely invisible — auto-capture would silently stop
working whenever the MemStack server was unreachable. Now logs network
errors and non-2xx responses via console.error while remaining
fire-and-forget (does not block turn completion).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ection

Delete the TypeScript bridge plugin (openclaw-bridge/) entirely. The
new model connects MemStack to OpenClaw as a native MCP server — the
agent calls memory tools explicitly as tool calls, with no hooks, no
auto-capture, and no auto-recall. Rewrote docs/connect-openclaw.md
with explicit memory_write + tags:["auto-capture"] workflow. Updated
README, CONTRIBUTING, CHANGELOG, .gitignore, and spec files. Fixed
pre-existing unused import in memories.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…P config

The disable-native-memory step was marked optional and placed after the
MCP server config step. Without disabling OpenClaw's native memory first,
the framework-level pipeline intercepts all memory operations and MemStack
tools are never called. Moved to Step 3 (before MCP config) and removed
the optional label.

Co-Authored-By: Claude Opus 4.7 <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