Skip to content

feat(retrieval): wire HRR structural-query lane into retrieve_v2 (#152) - #503

Merged
robotrocketscience merged 4 commits into
mainfrom
feat/issue-152-hrr-structural-wire
May 8, 2026
Merged

feat(retrieval): wire HRR structural-query lane into retrieve_v2 (#152)#503
robotrocketscience merged 4 commits into
mainfrom
feat/issue-152-hrr-structural-wire

Conversation

@robotrocketscience

@robotrocketscience robotrocketscience commented May 8, 2026

Copy link
Copy Markdown
Owner

Closes the loop on #152: the substrate (HRRStructIndex, parse_structural_marker, is_hrr_structural_enabled) was shipped at v1.7.0 but the integration into retrieve_v2 was deferred and never followed up. use_hrr_structural was a phantom flag — setting it ON changed no behavior because HRRIndex was never imported into retrieval.py. Audit on main HEAD f547779:

$ grep -rnE 'HRRIndex|parse_structural_marker' src/ --include='*.py' \
  | grep -v 'src/aelfrice/hrr_index.py'
(no matches)

This PR connects them.

Commits

  1. feat(hrr_index): HRRStructIndexCache for warm callers — mirrors VocabBridgeCache / BM25IndexCache. Lazy build, store-invalidation subscription, drop-on-mutate. Long-running consumers (interactive shells, future bench harness, retrieve_v2 with explicit cache) amortise the per-belief HRR encode cost across queries instead of rebuilding per call. 3 unit tests.

  2. feat(retrieval): wire HRR structural lane into retrieve_v2retrieve_v2 grows use_hrr_structural and hrr_struct_index_cache kwargs and a routing branch that fires before the vocab-bridge rewrite (a <KIND>:<target_id> marker must not be munged into bag-of-words expansions). On marker hit + flag ON the HRR lane returns directly with locks pinned and HRR-ranked beliefs packed against the budget; on miss the call falls through to the textual lane unchanged. Per spec the lanes are parallel, never blended.

  3. test(retrieval): integration tests for HRR structural-query routing — 6 end-to-end tests through retrieve_v2: (IT1) marker + flag ON returns HRR-ranked beliefs; (IT2) marker + flag OFF falls through to textual; (IT3) non-marker query + flag ON byte-identical to flag OFF; (IT4) marker with unknown target falls through gracefully; (IT5) explicit cache reuses the index across calls; (IT6) locks pin to head when structural lane fires.

  4. docs(retrieval): un-phantom use_hrr_structural with syntax cheatsheetCONFIG.md reflects the actual routing behavior + a 5-row example table covering hit / miss-by-text / miss-by-empty-target / miss-by-unknown-target / case-sensitivity.

Acceptance status

Acceptance State Notes
Substrate (#152) ✅ already shipped (v1.7.0) hrr_index.py, full unit tests
Flag resolution (is_hrr_structural_enabled) ✅ already shipped Env > kwarg > TOML > default-False precedence
Wired into retrieve_v2 this PR use_hrr_structural / hrr_struct_index_cache kwargs + routing branch
Integration tests proving the wiring ✅ this PR 6 end-to-end tests
Default-OFF preserved ✅ this PR Matches #154 policy until #437 reproducibility harness clears
#154 audit table fix follow-up comment after merge The "wired but stays opt-in" claim was wrong; comment lands once this is on main

Verification

  • New unit tests (cache): tests/test_hrr_struct_index.py — 21 passed, 2 skipped (perf-gated).
  • New integration tests: tests/test_retrieve_v2_hrr_structural.py — 6 passed.
  • Full non-bench-gate suite: 2924 passed, 26 skipped.
  • Discretion grep on git diff origin/main...HEAD → empty.

Default-flip plan

Stays default-OFF behind use_hrr_structural. The #154 composition tracker (currently 7/11 per #474 v2.1 umbrella) gates the flip; lab-side bench evidence required.

Out of scope

  • The default-flip itself (separate bench-gated PR).
  • A CLI surface for aelf:search "<KIND>:<id>" — current contract is library-API-only via retrieve_v2(use_hrr_structural=True). CLI exposure can land separately if/when the operator wants the marker syntax in the user-visible search verb.
  • Structural query autocomplete / discoverability tooling.
  • Latency microbench at N ∈ {10k, 50k} — tests/test_hrr_struct_index.py already has perf-gated tests for the index itself; the end-to-end retrieve_v2 latency is dominated by the HRR matvec which has its own AC7 budget.

Summary by Sourcery

Wire the HRR structural-query lane into retrieve_v2 and add a cache for the HRR structural index, with tests and documentation updates.

New Features:

  • Add HRRStructIndexCache to lazily build and reuse a structural HRR index across retrieval calls.
  • Introduce structural-query routing in retrieve_v2 controlled by use_hrr_structural and hrr_struct_index_cache parameters.

Enhancements:

  • Ensure structural HRR queries are handled as a separate lane that can short-circuit before textual retrieval while preserving lock pinning and token budget semantics.

Documentation:

  • Expand CONFIG.md to describe the HRR structural-query marker syntax, routing behavior, locking semantics, and cache usage.

Tests:

  • Add unit tests for HRRStructIndexCache behavior, including lazy build, reuse, and invalidation on store mutation.
  • Add integration tests for retrieve_v2 structural-query routing covering flag behavior, fallthrough cases, cache reuse, and lock handling.

Summary by CodeRabbit

  • New Features

    • Added structural-marker query routing to retrieve_v2 for improved retrieval precision.
    • Introduced use_hrr_structural parameter to enable/disable structural queries.
    • Added caching mechanism for query performance optimization in long-running scenarios.
  • Documentation

    • Expanded use_hrr_structural configuration documentation with behavioral specifications and usage guidance.
  • Tests

    • Added comprehensive integration and unit tests for structural-query routing and caching functionality.

Mirrors VocabBridgeCache and BM25IndexCache: lazy build, store-
invalidation subscription, drop-on-mutate. Long-running consumers
(retrieve_v2 with use_hrr_structural=True, future bench harness)
should pass an explicit cache to amortise the per-belief HRR
encode cost across queries instead of rebuilding per call.

Module-level docstring updated to reflect the wiring intent;
substrate-only framing was leftover from the deferred-integration
state. The actual retrieve_v2 routing lands in the next commit.

Tests: lazy_build_then_reuse, invalidate_on_store_mutation,
explicit_invalidate_drops_index. Existing 18 unit tests + 2 perf-
gated unchanged.
The substrate (HRRStructIndex, parse_structural_marker) and the
flag resolver (is_hrr_structural_enabled) were shipped at v1.7.0
but never connected: the flag was a phantom — setting it ON
changed no behavior because no retrieval entry point imported the
index or called the marker parser. PR audit on main HEAD f547779
found zero call sites outside hrr_index.py itself.

This commit closes the loop. retrieve_v2 grows two kwargs
(use_hrr_structural, hrr_struct_index_cache) and a routing branch
that fires BEFORE the vocab-bridge rewrite — a
'<KIND>:<target_id>' marker must not be munged into bag-of-words
expansions. On marker hit + flag ON the HRR lane returns directly
with locks pinned and the top-K HRR-ranked beliefs packed against
the budget; on miss (non-marker query, marker with unknown
target, or flag OFF) the call falls through to the textual lane
unchanged. Per spec the lanes are parallel, never blended.

Default-OFF preserved (matches #154 policy until #437
reproducibility harness clears). Locked beliefs continue to pin
to head and bypass the budget per the existing public-API
contract; HRR results are de-duped against the locked set so the
pin invariant holds.

Tests: 118 retrieval-area tests pass (test_retrieve_v2,
test_retrieval_cache, test_retrieval_l0_first,
test_retrieval_smoke, test_retrieval_token_budget,
test_retrieve_doc_anchors, test_retrieve_v2_temporal_sort,
test_compression_integration, test_vocab_bridge,
test_vocab_bridge_integration, test_clustering). Integration
tests for the new routing land in the next commit.
…152)

Six tests proving the wiring is real (not just module-shipped):

- IT1 marker + flag ON returns HRR-ranked beliefs (b1 -CONTRADICTS-> b2
  surfaces b1 for query 'CONTRADICTS:b2')
- IT2 marker + flag OFF falls through to textual lane (b1 absent
  because textual BM25 over the literal string 'CONTRADICTS:b2'
  cannot match content 'content of b1' — proves the structural
  lane was the only path that could surface it)
- IT3 non-marker query + flag ON byte-identical to flag OFF (the
  flag is a no-op on normal text queries, preserving default-OFF
  posture for non-marker traffic)
- IT4 marker + unknown target falls through to textual gracefully
  (no exception, valid RetrievalResult)
- IT5 explicit cache reuses the index across calls (cache._index
  identity stable across two retrieve_v2 calls)
- IT6 locks pin to head when the structural lane fires
  (locked_ids invariant preserved)

Each test is end-to-end through retrieve_v2 — exercises the
full kwarg surface, the routing branch, _route_structural_query,
HRRStructIndex.probe, and the budget pack.

Full non-bench-gate suite: 2924 passed, 26 skipped.
…#152)

The CONFIG.md entry from when the substrate landed (#152 close at
2026-04-28) said only 'lane is implemented and stays opt-in pending
the #154 benchmark gate' — true at the module level, misleading at
the integration level. Setting the flag did nothing then. Now it
does, so the doc reflects what actually happens.

Adds:
- Routing diagram (structural-marker hit -> HRRStructIndex; miss
  -> textual lane).
- The supported edge-type kinds + the case-sensitivity rule.
- A 5-row example table covering hit, miss-by-text, miss-by-empty-
  target, miss-by-unknown-target.
- The locked-pin invariant + budget pack semantics.
- The HRRStructIndexCache amortisation guidance for long-running
  callers.
- The precedence chain and the default-on flip gate (#154 bench).
@sourcery-ai

sourcery-ai Bot commented May 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

Wires the previously shipped HRR structural-query substrate into retrieve_v2 by adding a structural routing branch and cache, plus tests and documentation, so structural markers can be served via an HRR lane in parallel to the existing textual lane while remaining default-off.

Sequence diagram for retrieve_v2 HRR structural-query routing

sequenceDiagram
    actor Client
    participant RetrieveV2 as retrieve_v2
    participant FlagResolver as is_hrr_structural_enabled
    participant HRRRouter as _route_structural_query
    participant MarkerParser as parse_structural_marker
    participant Cache as HRRStructIndexCache
    participant Index as HRRStructIndex
    participant Store as MemoryStore
    participant TextualLane as textual_lane

    Client->>RetrieveV2: retrieve_v2(query, use_hrr_structural, hrr_struct_index_cache, ...)
    RetrieveV2->>FlagResolver: is_hrr_structural_enabled(use_hrr_structural)
    FlagResolver-->>RetrieveV2: enabled_flag

    alt HRR structural enabled
        RetrieveV2->>HRRRouter: _route_structural_query(Store, query, cache, top_k, include_locked, budget)
        HRRRouter->>MarkerParser: parse_structural_marker(query)
        MarkerParser-->>HRRRouter: (kind, target_id) or None

        alt query is structural marker
            alt cache is None
                HRRRouter->>Index: HRRStructIndex()
                HRRRouter->>Index: build(Store)
            else cache provided
                HRRRouter->>Cache: get()
                Cache-->>HRRRouter: Index
            end

            HRRRouter->>Index: probe(kind, target_id, top_k)
            Index-->>HRRRouter: hits

            alt hits not empty
                HRRRouter->>Store: list_locked_beliefs()
                Store-->>HRRRouter: locked_beliefs
                HRRRouter->>Store: get_belief(belief_id) for each hit
                Store-->>HRRRouter: belief or None
                HRRRouter-->>RetrieveV2: RetrievalResult(beliefs, locked_ids)
                RetrieveV2-->>Client: RetrievalResult
            else no hits
                HRRRouter-->>RetrieveV2: None
                RetrieveV2->>TextualLane: run textual retrieval stack
                TextualLane-->>RetrieveV2: RetrievalResult
                RetrieveV2-->>Client: RetrievalResult
            end
        else not a marker
            HRRRouter-->>RetrieveV2: None
            RetrieveV2->>TextualLane: run textual retrieval stack
            TextualLane-->>RetrieveV2: RetrievalResult
            RetrieveV2-->>Client: RetrievalResult
        end
    else HRR structural disabled
        RetrieveV2->>TextualLane: run textual retrieval stack
        TextualLane-->>RetrieveV2: RetrievalResult
        RetrieveV2-->>Client: RetrievalResult
    end
Loading

Class diagram for HRRStructIndexCache and related retrieval types

classDiagram
    class MemoryStore {
        +add_invalidation_callback(callback)
        +list_locked_beliefs() list~Belief~
        +get_belief(belief_id: str) Belief
    }

    class HRRStructIndex {
        +dim: int
        +build(store: MemoryStore, store_path: str, seed: int) void
        +probe(kind: str, target_id: str, top_k: int) list~tuple~
    }

    class HRRStructIndexCache {
        +store: MemoryStore
        +dim: int
        +store_path: str
        +seed: int
        -_index: HRRStructIndex
        -_subscribed: bool
        +__post_init__() void
        +get() HRRStructIndex
        +invalidate() void
    }

    class Belief {
        +id: str
    }

    class RetrievalResult {
        +beliefs: list~Belief~
        +locked_ids: list~str~
    }

    MemoryStore "1" --> "*" Belief : stores
    MemoryStore "1" --> "*" HRRStructIndexCache : used_by
    HRRStructIndexCache "1" o-- "0..1" HRRStructIndex : caches
    HRRStructIndex "1" --> "1" MemoryStore : built_from
    RetrievalResult "1" --> "*" Belief : beliefs
    RetrievalResult "1" --> "*" Belief : locked_via_ids
Loading

File-Level Changes

Change Details Files
Introduce HRRStructIndexCache to reuse HRR structural indices across calls with invalidation on store mutation.
  • Add HRRStructIndexCache dataclass that lazily builds an HRRStructIndex on first use and caches it.
  • Hook the cache into the store’s invalidation callbacks so belief/edge mutations drop the cached index.
  • Provide explicit invalidate() behavior, and unit tests covering lazy build/reuse and invalidation semantics.
src/aelfrice/hrr_index.py
tests/test_hrr_struct_index.py
Add HRR structural-query routing lane to retrieve_v2, including budget-aware packing and locked-belief handling.
  • Implement _route_structural_query helper that parses structural markers, builds or retrieves an HRRStructIndex (optionally via cache), probes for hits, and converts them to a RetrievalResult.
  • Ensure structural hits respect the token budget and keep locked beliefs pinned at the head, de-duplicating locked beliefs from HRR results.
  • Call _route_structural_query at the start of retrieve_v2 when is_hrr_structural_enabled(use_hrr_structural) is true, returning early on structural hits and falling through to the existing textual pipeline on non-markers or misses.
  • Extend retrieve_v2 signature to accept use_hrr_structural and hrr_struct_index_cache kwargs and document their behavior in the docstring.
src/aelfrice/retrieval.py
Add integration tests to validate HRR structural routing behavior end-to-end in retrieve_v2, including cache reuse and locked-belief semantics.
  • Create a MemoryStore fixture and helper functions to populate beliefs and edges forming a small structural topology.
  • Add tests asserting structural markers with the flag on return HRR-derived results, while markers with the flag off or unknown targets fall back to textual behavior.
  • Verify non-marker queries behave identically with the flag on or off, and that passing an explicit HRRStructIndexCache reuses the index across calls.
  • Assert that locked beliefs still pin to the head of results when the structural lane is used and are reflected in locked_ids.
tests/test_retrieve_v2_hrr_structural.py
Update configuration documentation to describe real HRR structural routing semantics and cache usage.
  • Expand CONFIG.md section for use_hrr_structural to show the routing diagram from structural marker parsing to either HRR structural lane or textual lane.
  • Document marker syntax, recognized edge types, case-sensitivity, and behavioral examples for hit, miss, and malformed markers.
  • Describe how locked beliefs interact with the structural lane and how to use the hrr_struct_index_cache parameter for long-running consumers.
  • Clarify precedence rules for use_hrr_structural and note that the default remains false pending benchmark gates.
docs/CONFIG.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@robotrocketscience robotrocketscience added author-Kulili PR coordination mutex attn:review Needs review (PR open, awaiting reviewer) labels May 8, 2026
@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR adds HRR structural-marker routing to retrieve_v2. A new HRRStructIndexCache lazily builds and caches indices with automatic invalidation on store mutations. The public API gains use_hrr_structural and hrr_struct_index_cache parameters. An early pre-vocab-bridge routing branch recognizes structural markers and returns HRR-ranked results immediately; marker hits bypass textual retrieval, while misses fall through. Six integration tests and three cache unit tests validate flag semantics, cache reuse, marker fallback, and locked belief pinning.

Changes

HRR Structural-Query Retrieval Lane

Layer / File(s) Summary
Cache Data Type & Lifecycle
src/aelfrice/hrr_index.py
HRRStructIndexCache dataclass lazily builds and holds a single HRRStructIndex, subscribes to store invalidation callbacks on init, and resets the cached index on mutations so subsequent get() rebuilds.
Structural Query Routing
src/aelfrice/retrieval.py
Imports for structural marker parsing; _route_structural_query helper parses markers, probes an HRRStructIndex, pins locked beliefs, de-dupes overlaps, and appends HRR-ranked results within token budget; returns None for non-markers or unknown targets.
Public API Extension & Early Routing
src/aelfrice/retrieval.py
retrieve_v2 signature adds use_hrr_structural and hrr_struct_index_cache parameters; function body adds pre-vocab-bridge branch that returns immediate structural-lane result when enabled and marker is recognized.
Cache Unit Tests
tests/test_hrr_struct_index.py
Three tests verify lazy build & reuse on multiple get() calls, automatic rebuild and new belief inclusion on store mutation, and explicit invalidate() clearing the cached index.
Integration Tests for Structural Routing
tests/test_retrieve_v2_hrr_structural.py
Six end-to-end tests verify marker routing with flag-on returns HRR results, flag-off bypasses structural lane, non-marker queries unaffected, unknown marker targets fall through gracefully, explicit cache instance reused across calls, and locked beliefs pin to head under structural lane.
Configuration Documentation
docs/CONFIG.md
CONFIG.md expanded with behavioral spec for [retrieval] use_hrr_structural: marker syntax/validation, fallback rules, concrete examples, locked-belief pinning and de-duplication, cache guidance, automatic invalidation, and explicit precedence for env var, kwarg, TOML, and default.

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: wiring the HRR structural-query lane into retrieve_v2, which is the central objective of the pull request.
Description check ✅ Passed The PR description fully complies with the template, including: detailed Summary (why the PR exists), Linked issues (Closes #152), Type of change (feat), Verification checklist items with test results, comprehensive Test plan, and thorough Notes for reviewer covering commits, acceptance status, and out-of-scope items.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-152-hrr-structural-wire

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Toug:2026-05-08T20:37:45Z]

@sourcery-ai sourcery-ai 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.

Hey - I've found 1 issue, and left some high level feedback:

  • In _route_structural_query, the non-cached path constructs HRRStructIndex() with only default parameters, while HRRStructIndexCache.get() wires through dim/store_path/seed; if callers rely on non-default dimensions or reproducible seeding you may want to expose equivalent configuration for the non-cached path to avoid subtle behavioral drift between the two.
  • Several tests (e.g. test_explicit_cache_reuses_index_across_calls) assert against cache._index directly; consider exposing a small public introspection method/property on HRRStructIndexCache so tests don’t need to reach into a private attribute.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_route_structural_query`, the non-cached path constructs `HRRStructIndex()` with only default parameters, while `HRRStructIndexCache.get()` wires through `dim/store_path/seed`; if callers rely on non-default dimensions or reproducible seeding you may want to expose equivalent configuration for the non-cached path to avoid subtle behavioral drift between the two.
- Several tests (e.g. `test_explicit_cache_reuses_index_across_calls`) assert against `cache._index` directly; consider exposing a small public introspection method/property on `HRRStructIndexCache` so tests don’t need to reach into a private attribute.

## Individual Comments

### Comment 1
<location path="tests/test_hrr_struct_index.py" line_range="281-286" />
<code_context>
+    assert "b6" in second.belief_ids
+
+
+def test_cache_explicit_invalidate_drops_index() -> None:
+    s = _toy_store()
+    cache = HRRStructIndexCache(store=s, dim=256, seed=7)
+    cache.get()
+    cache.invalidate()
+    assert cache._index is None
+
+
</code_context>
<issue_to_address>
**nitpick (testing):** Avoid asserting on the cache's private `_index` attribute or add a small public helper for this

This test relies on `cache._index`, which is a private implementation detail and makes `HRRStructIndexCache` harder to refactor safely. Instead, consider asserting via the public API—for example, compare the object returned by `cache.get()` before and after `invalidate()`. If you need to assert the empty state directly, you could add a small read-only helper (e.g. `is_built` or `peek_index`) and use that in the test.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +281 to +286
def test_cache_explicit_invalidate_drops_index() -> None:
s = _toy_store()
cache = HRRStructIndexCache(store=s, dim=256, seed=7)
cache.get()
cache.invalidate()
assert cache._index is None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nitpick (testing): Avoid asserting on the cache's private _index attribute or add a small public helper for this

This test relies on cache._index, which is a private implementation detail and makes HRRStructIndexCache harder to refactor safely. Instead, consider asserting via the public API—for example, compare the object returned by cache.get() before and after invalidate(). If you need to assert the empty state directly, you could add a small read-only helper (e.g. is_built or peek_index) and use that in the test.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

Reviewed (Toug, non-author per session-mutex labels — author-Kulili on PR).

4 atomic signed commits (672c719, b32e918, 7f0facc, 6a1f04e — all G).

Code:

  • HRRStructIndexCache (672c719): mirrors VocabBridgeCache / BM25IndexCache — lazy build, store-invalidation subscription via add_invalidation_callback, drop-on-mutate. __post_init__ self-subscribes once. Per-instance state. Module docstring reframed from substrate-only to wired-into-retrieve_v2.
  • Routing wire-up (b32e918): _route_structural_query fires before the vocab-bridge rewrite — correct, otherwise a <KIND>:<target> marker would be munged into bag-of-words rewrites. On marker hit + flag ON the HRR lane returns directly with locks pinned at head; on miss (non-marker, unknown target, or flag OFF) returns None and the call falls through to the textual lane unchanged. Per spec the lanes are parallel, never blended. Default-OFF byte-identity preserved (the is_hrr_structural_enabled resolver already shipped at v1.7.0).
  • Lock + budget invariants: locks pin to head and bypass budget (existing public-API contract); HRR-ranked beliefs are appended in score-descending order until budget exhausted; locked-set members are de-duped from the HRR tail to preserve the pin invariant. Verified by IT6.
  • Cache fall-through: if cache is None: HRRStructIndex().build(store) rebuilds per call for one-shot consumers; cached for warm callers. Documented.
  • Top-k mapping: top_k=l1_limit — uses the existing L1 cap as the structural-lane cap. Symmetric with how the textual lane treats l1_limit.

Tests:

  • 27/27 + 2 skipped pass locally (tests/test_retrieve_v2_hrr_structural.py + tests/test_hrr_struct_index.py).
  • IT1–IT6 cover marker-hit-flag-ON, flag-OFF fall-through (proves textual was the only path that could surface b1 for CONTRADICTS:b2), non-marker byte-identity, unknown-target graceful miss, cache reuse, and locks-pin-with-structural-on. End-to-end through retrieve_v2 — exercises the full kwarg surface, the routing branch, _route_structural_query, HRRStructIndex.probe, and the budget pack.

Docs (6a1f04e): docs/CONFIG.md § use_hrr_structural un-phantomed with the routing diagram, marker syntax cheatsheet, examples table, lock+budget contract, cache guidance, and precedence chain. Specifies the marker is case-sensitive and whitespace-stripping behavior.

CI: required gates SUCCESS at 6a1f04e. CodeQL python was the last in-progress check; cleared. consecutive-green ≥ 7d is the informational soak gate (same state under which #493/#495/#496/#497/#498/#500 merged).

Discretion: clean.

FF: confirmed (git merge-base --is-ancestor github/main refs/pull/503/head → true).

Cross-PR note: PR #502 (mine, post-#494 doc_linker leaf-module cleanup) is open. No file overlap — #503 only touches hrr_index.py / retrieval.py / tests / docs/CONFIG.md; #502 only touches doc_linker.py / store.py / new doc_linker_types.py. No conflict either way; whichever lands first doesn't affect the other.

Approving. Proceeding with local FF push merge.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Toug:2026-05-08T20:39:41Z]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

attn:review Needs review (PR open, awaiting reviewer) author-Kulili PR coordination mutex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant