Skip to content

fix: restore main CI contracts after merge#480

Merged
AxDSan merged 4 commits into
mnemosyne-oss:mainfrom
dplush:fix/main-ci-post-merge-alignment-clean
Jul 17, 2026
Merged

fix: restore main CI contracts after merge#480
AxDSan merged 4 commits into
mnemosyne-oss:mainfrom
dplush:fix/main-ci-post-merge-alignment-clean

Conversation

@dplush

@dplush dplush commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Restores main CI after the #456/#476/#478 merge sequence.

  • add the missing apply-pending schema to the Hermes integration copy
  • implement bounded exponential embedding-retry backoff with jitter
  • align the provider count and replace tests for the reverted lifecycle API with stable constructor coverage

Validation: focused regression suite (82 passed), py_compile, git diff --check.

Summary

  • Restores Hermes agent integration compatibility by registering the missing pending-memory commit tool (mnemosyne_apply_pending, APPLY_PENDING_SCHEMA). This re-enables the approved “staged/approved pending writes” flow to be committed through the BEAM write path (i.e., it fixes the integration surface contract rather than changing memory semantics).
  • Improves embedding-request resilience by switching embedding retry delays to bounded exponential backoff with randomized jitter for HTTP 429/5xx, network exceptions, and the message-text-based rate-limit fallback path—reducing retry stampedes without changing what data is sent.
  • Adjusts BEAM/polyphonic diversity behavior expectations by computing diversity similarity from PolyphonicResult.content when present (falling back to metadata["content"]), updating the related regression assertion accordingly.
  • Hardens long-term maintainability of the local-first/ownership lifecycle by replacing reverted lifecycle/disposal assertions with a stable “construction contract” test, and aligning tool-wiring tests to the updated exported tool count.

Impact across architecture & guarantees

  • Core memory architecture / tiered memory (working/episodic/BEAM): No tiered-memory logic changes in these diffs; the BEAM-related impact is limited to formalizing the expected pending-write commit tool wiring.
  • Retrieval strategies & consolidation/veracity/sync layers: Not modified.
  • Privacy posture & local-first guarantees: Low risk—APPLY_PENDING_SCHEMA commits existing staged/approved local pending records, and the embedding retry change alters timing only (not request payloads).
  • Agent integration surfaces (Hermes/MCP/CLI): Hermes is directly fixed; MCP/CLI surfaces are not indicated as changed.
  • Validation: 82 passing focused regression tests, py_compile, and git diff --check.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 498e234b-4923-4170-913d-a04c74ad0bea

📥 Commits

Reviewing files that changed from the base of the PR and between 6cb5d7d and 053a533.

📒 Files selected for processing (1)
  • mnemosyne/core/polyphonic_recall.py

📝 Walkthrough

Walkthrough

The PR registers a pending-memory application tool, adds randomized backoff to embedding API retries, updates polyphonic recall similarity calculation, and revises related regression coverage.

Changes

Pending memory tool registration

Layer / File(s) Summary
Pending tool schema and registration
integrations/hermes/src/mnemosyne_hermes/tools.py, tests/test_provider_all_15_tools.py
Adds mnemosyne_apply_pending with required pending record IDs, registers it in the complete tool schema list, and updates the registration count to 40 tools.

Embedding retry jitter

Layer / File(s) Summary
Jittered embedding retries
mnemosyne/core/embeddings.py
Adds a randomized retry-delay helper and uses it for HTTP, network, and message-detected rate-limit retry paths.

Polyphonic recall and regression updates

Layer / File(s) Summary
Similarity source and expectations
mnemosyne/core/polyphonic_recall.py, tests/test_beam_e5_polyphonic_recall.py, tests/test_memory_lifecycle.py
Computes similarity from PolyphonicResult.content when available, updates the expected similarity to 0.0, and revises the lifecycle test module description.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: axdsan

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main goal of restoring CI-related contracts after the merge sequence.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_memory_lifecycle.py (1)

6-11: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Restore the deleted lifecycle regression coverage.

This smoke test does not replace the removed Mnemosyne.__del__ and multi-owner close/reconnection tests: cleanup and reopen regressions can now pass CI unnoticed. Also assert that the remembered record is persisted and retrievable, rather than checking only that remember() returned a string.

As per path instructions, tests/** must maintain comprehensive, meaningful coverage of lifecycle and cross-session behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_memory_lifecycle.py` around lines 6 - 11, Expand
test_mnemosyne_initializes_beam_and_can_remember to verify the remembered record
is persisted and retrievable, then restore dedicated regression coverage for
Mnemosyne cleanup via __del__ and for closing/reconnecting with multiple owners
or sessions. Keep the tests focused on lifecycle behavior and cross-session
persistence, using the existing public APIs and asserting records remain
available after reopen.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integrations/hermes/src/mnemosyne_hermes/tools.py`:
- Around line 797-802: The Hermes documentation’s tool registry listing is
outdated. Update the tools section in README.md to state 40 tools and add
mnemosyne_apply_pending alongside the existing documented tools, using
ALL_TOOL_SCHEMAS as the source of truth.

In `@tests/test_provider_all_15_tools.py`:
- Around line 52-55: Add focused assertions to test_all_tools_registered using
the existing provider tool metadata: verify mnemosyne_apply_pending is
registered, and validate its schema requires pending_ids as an array whose items
are strings. Keep the aggregate tool-count assertion, but ensure the new checks
independently detect missing or incorrectly defined registration.

---

Outside diff comments:
In `@tests/test_memory_lifecycle.py`:
- Around line 6-11: Expand test_mnemosyne_initializes_beam_and_can_remember to
verify the remembered record is persisted and retrievable, then restore
dedicated regression coverage for Mnemosyne cleanup via __del__ and for
closing/reconnecting with multiple owners or sessions. Keep the tests focused on
lifecycle behavior and cross-session persistence, using the existing public APIs
and asserting records remain available after reopen.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: aed422c3-be7f-43ab-89a7-9d1a14baf561

📥 Commits

Reviewing files that changed from the base of the PR and between e5adea1 and 39329fa.

📒 Files selected for processing (4)
  • integrations/hermes/src/mnemosyne_hermes/tools.py
  • mnemosyne/core/embeddings.py
  • tests/test_memory_lifecycle.py
  • tests/test_provider_all_15_tools.py

Comment on lines 797 to +802
ALL_TOOL_SCHEMAS = [
REMEMBER_SCHEMA, RECALL_SCHEMA, SHARED_REMEMBER_SCHEMA, SHARED_RECALL_SCHEMA,
SHARED_FORGET_SCHEMA, SHARED_STATS_SCHEMA, SLEEP_SCHEMA, STATS_SCHEMA,
INVALIDATE_SCHEMA, VALIDATE_SCHEMA, GET_SCHEMA, TRIPLE_ADD_SCHEMA, TRIPLE_QUERY_SCHEMA,
TRIPLE_END_SCHEMA,
REMEMBER_CANONICAL_SCHEMA, RECALL_CANONICAL_SCHEMA, FORGET_CANONICAL_SCHEMA, MODEL_CARD_SCHEMA,
REMEMBER_CANONICAL_SCHEMA, RECALL_CANONICAL_SCHEMA, FORGET_CANONICAL_SCHEMA, APPLY_PENDING_SCHEMA, MODEL_CARD_SCHEMA,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Files ==\n'
git ls-files integrations/hermes/src/mnemosyne_hermes/tools.py integrations/hermes/README.md integrations/hermes | sed 's#^`#-` #'

printf '\n== Tool schema list around the cited lines ==\n'
sed -n '780,830p' integrations/hermes/src/mnemosyne_hermes/tools.py | cat -n

printf '\n== README references to tools/count/memory guidance ==\n'
rg -n "tool|Tools|memory|Mnemosyne|disable memory|40|apply_pending|mnemosyne_apply_pending" integrations/hermes/README.md

printf '\n== Count ALL_TOOL_SCHEMAS entries by source text ==\n'
python3 - <<'PY'
import re, pathlib
path = pathlib.Path('integrations/hermes/src/mnemosyne_hermes/tools.py')
text = path.read_text()
m = re.search(r'ALL_TOOL_SCHEMAS\s*=\s*\[(.*?)\n\]', text, re.S)
if not m:
    print('ALL_TOOL_SCHEMAS block not found')
    raise SystemExit(1)
block = m.group(1)
items = re.findall(r'([A-Z_]+_SCHEMA)\b', block)
print('count_in_block=', len(items))
print('last_10=', items[-10:])
PY

Repository: mnemosyne-oss/mnemosyne

Length of output: 7211


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- README excerpts ---'
sed -n '1,260p' integrations/hermes/README.md | cat -n | sed -n '1,260p'

echo
echo '--- tool schema names in tools.py ---'
python3 - <<'PY'
import re, pathlib
text = pathlib.Path('integrations/hermes/src/mnemosyne_hermes/tools.py').read_text()
m = re.search(r'ALL_TOOL_SCHEMAS\s*=\s*\[(.*?)\n\]', text, re.S)
if not m:
    print('missing ALL_TOOL_SCHEMAS')
    raise SystemExit(1)
block = m.group(1)
items = re.findall(r'([A-Z_]+_SCHEMA)\b', block)
print('COUNT', len(items))
for i, item in enumerate(items, 1):
    print(f'{i:02d} {item}')
PY

Repository: mnemosyne-oss/mnemosyne

Length of output: 11947


🏁 Script executed:

#!/bin/bash
set -euo pipefail
printf 'README matches:\n'
rg -n "40 tools|39 tools|mnemosyne_apply_pending|apply_pending|disable memory|memory tools" integrations/hermes/README.md || true
printf '\nALL_TOOL_SCHEMAS count:\n'
python3 - <<'PY'
import re, pathlib
text = pathlib.Path('integrations/hermes/src/mnemosyne_hermes/tools.py').read_text()
m = re.search(r'ALL_TOOL_SCHEMAS\s*=\s*\[(.*?)\n\]', text, re.S)
items = re.findall(r'([A-Z_]+_SCHEMA)\b', m.group(1)) if m else []
print(len(items))
print(items[-6:])
PY

Repository: mnemosyne-oss/mnemosyne

Length of output: 634


Update the Hermes docs to match the current tool registry.
integrations/hermes/README.md still says 23 tools, but ALL_TOOL_SCHEMAS now exposes 40. Update the count, and add mnemosyne_apply_pending to the documented tool surface if this section is meant to enumerate it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/hermes/src/mnemosyne_hermes/tools.py` around lines 797 - 802,
The Hermes documentation’s tool registry listing is outdated. Update the tools
section in README.md to state 40 tools and add mnemosyne_apply_pending alongside
the existing documented tools, using ALL_TOOL_SCHEMAS as the source of truth.

Source: Path instructions

Comment on lines 52 to +55
def test_all_tools_registered(self, tmp_path):
provider = _provider(tmp_path)
names = _tool_names(provider)
assert len(names) == 39, f"Expected 39 tools, got {len(names)}"
assert len(names) == 40, f"Expected 40 tools, got {len(names)}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add a focused regression test for mnemosyne_apply_pending.

Updating the aggregate count does not prove the new tool is registered; the test could still pass with a missing tool and an unrelated duplicate. Assert that mnemosyne_apply_pending exists and that its schema requires an array of string pending_ids.

Suggested coverage
     def test_all_tools_registered(self, tmp_path):
         provider = _provider(tmp_path)
         names = _tool_names(provider)
         assert len(names) == 40, f"Expected 40 tools, got {len(names)}"
+
+    def test_apply_pending_tool_present(self, tmp_path):
+        provider = _provider(tmp_path)
+        schemas = provider.get_tool_schemas()
+        schema = next(s for s in schemas if s["name"] == "mnemosyne_apply_pending")
+        assert schema["parameters"]["required"] == ["pending_ids"]
+        assert schema["parameters"]["properties"]["pending_ids"] == {
+            "type": "array",
+            "items": {"type": "string"},
+            "description": schema["parameters"]["properties"]["pending_ids"]["description"],
+        }

As per path instructions: “Ensure strong coverage of: ... MCP tool surface ... Flag missing or weak test scenarios.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_all_tools_registered(self, tmp_path):
provider = _provider(tmp_path)
names = _tool_names(provider)
assert len(names) == 39, f"Expected 39 tools, got {len(names)}"
assert len(names) == 40, f"Expected 40 tools, got {len(names)}"
def test_all_tools_registered(self, tmp_path):
provider = _provider(tmp_path)
names = _tool_names(provider)
assert len(names) == 40, f"Expected 40 tools, got {len(names)}"
def test_apply_pending_tool_present(self, tmp_path):
provider = _provider(tmp_path)
schemas = provider.get_tool_schemas()
schema = next(s for s in schemas if s["name"] == "mnemosyne_apply_pending")
assert schema["parameters"]["required"] == ["pending_ids"]
assert schema["parameters"]["properties"]["pending_ids"] == {
"type": "array",
"items": {"type": "string"},
"description": schema["parameters"]["properties"]["pending_ids"]["description"],
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_provider_all_15_tools.py` around lines 52 - 55, Add focused
assertions to test_all_tools_registered using the existing provider tool
metadata: verify mnemosyne_apply_pending is registered, and validate its schema
requires pending_ids as an array whose items are strings. Keep the aggregate
tool-count assertion, but ensure the new checks independently detect missing or
incorrectly defined registration.

Source: Path instructions

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_beam_e5_polyphonic_recall.py (1)

194-199: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make this assertion hit the field _estimate_similarity actually reads. _hydrate_result_content only populates result.content, while similarity uses metadata["content"]; with empty metadata here, the 0.0 check passes even if hydration breaks. Use overlapping content and assert a non-zero Jaccard score, or put the source text into metadata["content"].

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_beam_e5_polyphonic_recall.py` around lines 194 - 199, Update the
test around _hydrate_result_content and _estimate_similarity so the compared
results contain source text in metadata["content"], which is the field
similarity reads. Use overlapping content and assert the expected non-zero
Jaccard score, ensuring the assertion fails if hydration or metadata content
handling is broken.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/test_beam_e5_polyphonic_recall.py`:
- Around line 194-199: Update the test around _hydrate_result_content and
_estimate_similarity so the compared results contain source text in
metadata["content"], which is the field similarity reads. Use overlapping
content and assert the expected non-zero Jaccard score, ensuring the assertion
fails if hydration or metadata content handling is broken.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d6f4621d-239f-4dc8-8002-40eee8c2f768

📥 Commits

Reviewing files that changed from the base of the PR and between 39329fa and 6cb5d7d.

📒 Files selected for processing (1)
  • tests/test_beam_e5_polyphonic_recall.py

@dplush

dplush commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@AxDSan #480 is ready to merge.

Full CI is green across Python 3.10–3.13, plus build, docs, CLA, and CodeRabbit.

It restores the post-merge contracts introduced across #456/#476/#478:

No uv.lock changes are included.

@dplush

dplush commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

After #480 lands, I suggest one clean main CI verification, then closing #473 and #475 if the shipped changes fully cover their reports.

The next substantive item is #474, which I’d treat as a separate design-first effort: make the FastEmbed/sqlite-vec capability state observable end-to-end, avoid silent FTS-only degradation, and reproduce the embedding-storage/FK path before changing it.

I’d avoid folding that into another quick stabilization PR.

@AxDSan
AxDSan merged commit 38bc21b into mnemosyne-oss:main Jul 17, 2026
8 checks passed
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.

2 participants