feat(miner): integrate compute_hallways_for_wing into post-mine flow#1560
Merged
igorls merged 1 commit intoMay 20, 2026
Merged
Conversation
Wires the hallway primitive (from PR #1558) into the project miner so that every mine that touches a wing also materializes within-wing entity hallways for that wing. Without this integration, the hallway module is dead code — no miner triggers it, no hallways ever land in ~/.mempalace/hallways.json. ## What this commit does 1. Adds a module-level import of ``compute_hallways_for_wing`` from ``.hallways`` near the top of ``miner.py``. Module-level (not lazy) so tests can patch it as ``mempalace.miner.compute_hallways_for_wing`` — lazy imports inside a function wouldn't expose the seam. 2. In ``_mine_impl``, immediately after the existing ``_compute_topic_tunnels_for_wing(wing)`` post-mine block, adds a parallel hallway block. The block: - calls ``compute_hallways_for_wing(wing, col=collection)`` - prints the count if any hallways were materialized - wraps the whole thing in try/except so a hallway-compute failure is logged + degraded, never propagated. Mirrors the tunnel block's fault-tolerance pattern exactly. Hallway computation is a derived analytic, not load-bearing for the drawer write that already committed above. ## Stacking This PR stacks on PR #1558 (which introduces the hallway primitive module). PR #1558 is the prerequisite — without it, the import ``from .hallways import compute_hallways_for_wing`` doesn't resolve. Base branch for this PR is ``feat/hallways-within-wing-connectors`` (PR #1558's branch). When PR #1558 merges to develop, GitHub will auto-update this PR's base to develop and the diff will reduce to just the miner.py and tests/test_miner.py changes. ## Out of scope (deferred to follow-up PRs) - ``format_miner.py`` integration: lives on a different branch (PR #1555) so the parallel call there goes in as a follow-up amendment to that branch (or a separate post-merge PR). - ``convo_miner.py`` integration: convo_miner currently doesn't call ``_compute_topic_tunnels_for_wing`` either. Adding both calls is a separate concerned PR about convo_miner parity, not just hallways. - Refactoring ``_compute_topic_tunnels_for_wing`` to BUILD ON hallways (rather than computing from raw topic words): the architecturally meaningful follow-up that completes the Wing → Drawer-entities → Hallway → Tunnel sequence. Real refactor, separate PR. ## Tests Two new RED-first tests in ``tests/test_miner.py``: test_mine_computes_hallways_for_wing_post_mine Stubs ``mempalace.miner.compute_hallways_for_wing`` via monkeypatch. Runs a real mine into a tmp palace. Asserts the stub was called exactly once, with the wing name from mempalace.yaml and a live ChromaDB collection (not None). test_mine_hallway_failure_does_not_crash_mine Stubs the hallway function to raise. Runs a real mine. Asserts mine() doesn't propagate, and that the drawer write (which happens BEFORE the hallway block) still committed. Both RED before this commit (AttributeError — module had no attribute ``compute_hallways_for_wing``). Both GREEN after. ## Verification ruff check mempalace/miner.py tests/test_miner.py → All checks passed! ruff format --check ... → 2 files already formatted (pinned 0.15.9) pytest tests/test_miner.py → 47 passed (the 2 new + 45 pre-existing) pytest -q (full mempalace suite) → 1938 passed, 1 skipped, 0 regressions Linux CI parity replicated locally via OrbStack containers (Python 3.9, 3.11, 3.13): 2/2 new integration tests pass, ruff clean on all three.
Contributor
There was a problem hiding this comment.
Code Review
This pull request integrates hallway computation into the mining process by calling compute_hallways_for_wing within _mine_impl. The implementation uses a try-except block to ensure that failures in this derived analytic do not crash the main mining operation. Corresponding integration tests have been added to verify the call occurs correctly and that exceptions are handled gracefully. I have no feedback to provide.
igorls
approved these changes
May 20, 2026
mvalentsev
pushed a commit
to mvalentsev/mempalace
that referenced
this pull request
May 21, 2026
Adds the architectural counterpart to ``compute_topic_tunnels`` that materializes cross-wing tunnels from the within-wing hallway records introduced in PR MemPalace#1558. When an entity (person, project, concept, interest) has hallways in two wings, an entity tunnel bridges them — anchored on the entity. This completes the v4 sequence: Wing → Drawer-entities → Hallway → Tunnel. Topic tunnels are NOT replaced. Both systems coexist for one release cycle so existing palaces don't lose tunnels between mines. Deprecation of topic tunnels is a separate follow-up PR after entity tunnels prove out in real use. ## What this commit does 1. Adds ``entity_tunnels_for_wing(wing, hallways, label_prefix)`` to ``mempalace/palace_graph.py``. Pure function: groups hallway records by entity-and-wing, finds entities present in ``wing`` AND ≥1 other wing, and emits one ``create_tunnel`` call per (entity, other_wing) pair. Uses ``kind="entity"`` and synthetic endpoint room ``entity:<name>`` so the new tunnels are distinguishable from explicit/topic tunnels at read time but interchangeable with them via the standard ``list_tunnels`` / ``follow_tunnels`` API. 2. Adds ``_compute_entity_tunnels_for_wing(wing)`` wrapper to ``mempalace/miner.py``. Loads hallway records via ``hallways.list_hallways()`` and calls the algorithm. Module-level so tests can patch it as ``mempalace.miner._compute_entity_tunnels_for_wing``. 3. Wires the wrapper into ``_mine_impl`` immediately after the existing hallway-compute block. Same try/except fault-tolerance pattern as the topic-tunnel and hallway blocks — entity-tunnel computation is a derived analytic and must never fail a mine. ## Tests (RED-first) Nine algorithm tests in ``tests/test_palace_graph_tunnels.py`` (new ``TestEntityTunnels`` class): test_entity_tunnels_creates_cross_wing_tunnel_for_shared_entity test_entity_tunnels_skips_entities_in_only_one_wing test_entity_tunnels_counts_entity_in_either_pair_position test_entity_tunnels_three_wings_pairwise_from_focus_wing test_entity_tunnels_idempotent_on_rerun test_entity_tunnels_retrievable_via_list_tunnels test_entity_tunnels_empty_hallways_is_noop test_entity_tunnels_unknown_wing_is_noop test_entity_tunnel_room_does_not_collide_with_literal_room Two integration tests in ``tests/test_miner.py``: test_mine_computes_entity_tunnels_for_wing_post_mine test_mine_entity_tunnel_failure_does_not_crash_mine All 11 RED before this commit (AttributeError on the missing names). All 11 GREEN after. ## Out of scope (deferred to follow-up PRs) - ``format_miner.py`` and ``convo_miner.py`` integration: separate PRs per the scope discipline used for MemPalace#1560. - Deprecating ``_compute_topic_tunnels_for_wing``: separate PR after entity tunnels prove out in real use. - Surfacing ``kind="entity"`` in MCP / search-result UI: not yet required by any reader; behaviorally interchangeable with the other tunnel kinds today. ## Stacking This PR stacks on PR MemPalace#1558 (which introduces the hallway primitive and its miner integration). Base branch is ``feat/hallways-within-wing-connectors``. When MemPalace#1558 merges to develop, GitHub auto-updates this PR's base to ``develop`` and the diff reduces to just the entity-tunnel additions. ## Verification pytest tests/test_palace_graph_tunnels.py::TestEntityTunnels → 9 passed (RED before, GREEN after) pytest tests/test_miner.py::test_mine_computes_entity_tunnels_for_wing_post_mine tests/test_miner.py::test_mine_entity_tunnel_failure_does_not_crash_mine → 2 passed (RED before, GREEN after) pytest tests/test_palace_graph_tunnels.py → 39 passed (no regressions) pytest tests/test_miner.py → 49 passed (no regressions) pytest -q (full mempalace suite) → 1949 passed, 1 skipped, 0 regressions ruff check mempalace/palace_graph.py mempalace/miner.py tests/ → All checks passed! ruff format --check ... → 4 files already formatted (pinned 0.15.9)
arnoldwender
pushed a commit
to arnoldwender/mempalace
that referenced
this pull request
May 24, 2026
Bumps version 3.3.5 → 3.3.6 across pyproject.toml, version.py, plugin manifests (.claude-plugin/plugin.json, .claude-plugin/marketplace.json, .codex-plugin/plugin.json), README badge, and uv.lock. Flips CHANGELOG.md from ``[Unreleased]`` to ``[3.3.6] — 2026-05-24`` and backfills the major user-facing entries that landed without changelog entries during the cycle: Features: - MemPalace#1555 office-document mining via --mode extract + virtual line numbers - MemPalace#1584 surgical closet pointers with date+line locators (Tier 6a) - MemPalace#1558 + MemPalace#1560 within-wing hallways (entity co-occurrence graph) - MemPalace#1565 cross-wing tunnels auto-promoted from hallways - MemPalace#1578 Hebbian potentiation + Ebbinghaus decay on hallways/tunnels - MemPalace#1236 API-tool transcripts auto-route to wing_api - MemPalace#711 hooks.auto_save toggle for silent-mode sessions - MemPalace#1605 COCA content-word filter for entity detection - MemPalace#1557 case-insensitive entity matching at mine time - MemPalace#1483 multilingual embeddings (embeddinggemma-300m) by default Bug Fixes (selected, user-visible): - MemPalace#1540 silent data loss in three unchunked upsert sites - MemPalace#1538 paragraph chunker oversized chunks - MemPalace#1554 per-file chunk cap too low for transcripts - MemPalace#1562 Windows hook subprocess/ChromaDB deadlock - MemPalace#1529 create_tunnel corrupted hyphenated wing names - MemPalace#1424 save-hook truncated hyphenated project folders - MemPalace#1383 KG cache duplicated graphs for symlinked/cased paths - MemPalace#1466 silent symlink skip now logged - MemPalace#1441 macOS stock-bash 3.2 hook compatibility - MemPalace#1500 / MemPalace#1513 structured JSON-RPC errors on bad MCP input - MemPalace#1523 VACUUM + FTS5 rebuild after repair - MemPalace#1548 FTS5 validation at end of mine - plus MemPalace#1216, MemPalace#1408, MemPalace#1438, MemPalace#1439, MemPalace#1445, MemPalace#1452, MemPalace#1459, MemPalace#1461, MemPalace#1466, MemPalace#1470, MemPalace#1477, MemPalace#1485, MemPalace#1500, MemPalace#1513, MemPalace#1528, MemPalace#1532, MemPalace#1543, MemPalace#1546, MemPalace#1585 Performance: - MemPalace#1474 convo miner pre-fetches mined-set - MemPalace#1487 rebuild_index progress callback - MemPalace#1530 MCP cold-start diagnostics + opt-in warmup Lint passes (ruff 0.15.14); mempalace-mcp entry point alignment verified per RELEASING.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires the hallway primitive from PR #1558 into the project miner's post-mine flow.
Why this is necessary
PR #1558 introduces the
compute_hallways_for_wingfunction — but no miner calls it yet. Without this integration, that module is dead code: no hallways ever materialize in~/.mempalace/hallways.json.This PR wires the call into
_mine_implso every project mine triggers hallway computation for the wing it just touched.What changes
Module-level import in
miner.py:Module-level (not lazy inside a function) so tests can patch the seam as
mempalace.miner.compute_hallways_for_wing.Post-mine call block in
_mine_impl, immediately after the existing topic-tunnel computation. Mirrors that block's fault-tolerance pattern exactly:Hallway computation is a derived analytic. If it fails, the drawer write (which happens earlier in
_mine_impl) has already committed. The failure must never propagate.Tests
Two new RED-first tests in
tests/test_miner.py:test_mine_computes_hallways_for_wing_post_minetest_mine_hallway_failure_does_not_crash_mineBoth RED before this commit (
AttributeError: module had nocompute_hallways_for_wingattribute). Both GREEN after.Verification
ruff check+ruff format --checktests/test_miner.pyOut of scope (deferred to follow-up PRs)
format_miner.pyintegration — lives on a different branch (PR feat(3.3.6): virtual line numbering + format coverage via --mode extract #1555). Goes in as an amendment commit there once feat(hallways): within-wing entity-to-entity connector primitive #1558 lands.convo_miner.pyintegration — convo_miner currently doesn't call_compute_topic_tunnels_for_wingeither. Adding both calls (tunnels + hallways) is a separate concerned PR about convo_miner parity._compute_topic_tunnels_for_wingto BUILD ON hallways — the architecturally meaningful follow-up that completes the Wing → Drawer-entities → Hallway → Tunnel sequence per the design. Real refactor, separate PR.This PR is intentionally narrow: just turn on hallway computation for the most-used miner. Convo / format miners follow in stacked PRs.