Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This is the reference for power users whose project has a documentation idiom or
A single optional TOML file at the root of a project (or any ancestor). It exposes two power-user surfaces:

- `[noise]` — onboard-time belief filter. Changes how `aelf onboard` ingests beliefs; nothing else.
- `[retrieval]` (v1.3+) — retrieval-time tier toggles + ranking. Knobs: `entity_index_enabled` (L2.5), `bfs_enabled` (L3), `posterior_weight` (partial Bayesian-weighted L1 ranking), `use_bm25f_anchors` (BM25F-with-anchor-text since v1.7), `use_heat_kernel` (authority scoring lane, opt-in), `use_hrr_structural` (HRR structural-query lane, opt-in), `use_type_aware_compression` (per-belief retention-class compression, opt-in since v2.1). Two placeholder flags (`use_signed_laplacian`, `use_posterior_ranking`) are recognised but emit a deprecation warning if set — their lanes have not yet shipped.
- `[retrieval]` (v1.3+) — retrieval-time tier toggles + ranking. Knobs: `entity_index_enabled` (L2.5), `bfs_enabled` (L3), `posterior_weight` (partial Bayesian-weighted L1 ranking), `use_bm25f_anchors` (BM25F-with-anchor-text since v1.7), `use_heat_kernel` (authority scoring lane, opt-in), `use_hrr_structural` (HRR structural-query lane, opt-in), `use_type_aware_compression` (per-belief retention-class compression, opt-in since v2.1), `use_vocab_bridge` (HRR query-side vocabulary bridge, opt-in since v2.1). Two placeholder flags (`use_signed_laplacian`, `use_posterior_ranking`) are recognised but emit a deprecation warning if set — their lanes have not yet shipped.

Locks, hooks, MCP tools, and the Bayesian feedback math are not affected.

Expand Down Expand Up @@ -88,6 +88,16 @@ use_hrr_structural = false
# overrides.
use_type_aware_compression = false

# v2.1 #433 HRR vocabulary bridge. When true, retrieve_v2 builds a
# per-store VocabBridge over surface forms (anchor text + belief
# content) and rewrites the query before lane fan-out, appending
# canonical-entity tokens whose recovery cosine clears the noise
# floor. Original tokens are preserved verbatim; the rewrite is
# additive, never substitutive. Default-OFF until the lab-side
# bench gate (A2 in docs/feature-hrr-vocab-bridge.md) clears.
# AELFRICE_VOCAB_BRIDGE=1 env var overrides.
use_vocab_bridge = false

# Placeholder flags reserved by #154 — recognised so callers can
# write forward-compat config, but their lanes have not yet
# shipped. Setting either to true emits a one-shot stderr
Expand Down Expand Up @@ -309,6 +319,23 @@ When disabled (default), `compressed_beliefs` is empty and `beliefs` is byte-ide

Precedence (first decisive wins): env var `AELFRICE_TYPE_AWARE_COMPRESSION=0`/`1` > explicit Python kwarg `use_type_aware_compression=<bool>` > TOML `[retrieval] use_type_aware_compression` > default `false`. The default-on flip is gated on the lab-side bench in `tests/bench_gate/test_compression_uplift.py` plus the pack-loop budget rewrite (follow-up).

### `use_vocab_bridge`

Boolean, default `false`, opt-in (v2.1+, #433). Enables the HRR vocabulary-bridge query rewrite. When on, `retrieve_v2` builds (or fetches a cached) `VocabBridge` over the per-project store and prepends the rewrite stage before lane fan-out:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (typo): Clarify the phrase "fetches a cached" to avoid a dangling adjective.

"builds (or fetches a cached) VocabBridge" is slightly ungrammatical because "cached" lacks a noun. Consider rephrasing to "builds (or fetches a cached VocabBridge)" or "builds (or fetches a cached instance of VocabBridge)" for clarity.

Suggested change
Boolean, default `false`, opt-in (v2.1+, #433). Enables the HRR vocabulary-bridge query rewrite. When on, `retrieve_v2` builds (or fetches a cached) `VocabBridge` over the per-project store and prepends the rewrite stage before lane fan-out:
Boolean, default `false`, opt-in (v2.1+, #433). Enables the HRR vocabulary-bridge query rewrite. When on, `retrieve_v2` builds (or fetches a cached instance of `VocabBridge`) over the per-project store and prepends the rewrite stage before lane fan-out:


```
query
-> [bridge.rewrite(query) if use_vocab_bridge else query]
-> retrieve() lane fan-out: BM25F + heat-kernel + HRR-structural + BFS
-> compose -> rank -> pack
```

The bridge is **not** a lane — it does not contribute scores. It harvests surface-form tokens from incoming anchor text (#148) and belief content (entity-extractor lane), constructs a single HRR composite per `(token, canonical)` pair, and at query time unbinds the query token to recover one or more canonical-entity strings via cleanup memory. Tokens that are themselves canonical self-recover and are appended once; tokens with no canonical above the noise floor (`1/sqrt(dim)`) drop. Original-query tokens are preserved verbatim — bridged candidates are appended, never substituted.

`use_hrr` on `retrieve_v2` is a deprecated alias for `use_vocab_bridge` and survives one minor version. Lab v2.0.0 adapters that pass `use_hrr=True` route to the bridge automatically; new callers should use `use_vocab_bridge` directly.

Precedence (first decisive wins): env var `AELFRICE_VOCAB_BRIDGE=0`/`1` > explicit Python kwarg `use_vocab_bridge=<bool>` > TOML `[retrieval] use_vocab_bridge` > default `false`. The default-on flip is gated on the lab-side bench in `tests/bench_gate/test_vocab_bridge_uplift.py` plus the strict A2 NDCG@k follow-up.

### Placeholder flags

`use_signed_laplacian` and `use_posterior_ranking` are reserved by #154 but their owning lanes have not yet shipped. The flags are recognised by `warn_placeholder_flags()` so writing them in `.aelfrice.toml` does not error; setting either to `true` emits a one-shot stderr deprecation warning and is otherwise a no-op. Source of truth: `PLACEHOLDER_FLAGS` in `src/aelfrice/retrieval.py`.
Expand Down
84 changes: 80 additions & 4 deletions src/aelfrice/retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
)
from aelfrice.bm25 import BM25IndexCache
from aelfrice.compression import CompressedBelief, compress_for_retrieval
from aelfrice.vocab_bridge import VocabBridge, VocabBridgeCache
from aelfrice.entity_extractor import extract_entities
from aelfrice.graph_spectral import (
DEFAULT_BM25_SEED_TOP_K,
Expand Down Expand Up @@ -137,6 +138,11 @@
# CompressedBelief renderings; OFF leaves the field empty for byte-identical
# behavior with v1.x adapters.
TYPE_AWARE_COMPRESSION_FLAG: Final[str] = "use_type_aware_compression"
# v2.1 #433 HRR vocabulary-bridge flag. Default-OFF at v2.0.0 until the
# lab-side bench gate (A2 in docs/feature-hrr-vocab-bridge.md) clears.
# When ON, retrieve_v2 builds (or fetches a cached) VocabBridge against
# the store and rewrites the query before lane fan-out.
VOCAB_BRIDGE_FLAG: Final[str] = "use_vocab_bridge"

PLACEHOLDER_FLAGS: Final[tuple[str, ...]] = (
SIGNED_LAPLACIAN_FLAG,
Expand All @@ -163,6 +169,8 @@
ENV_HRR_STRUCTURAL: Final[str] = "AELFRICE_HRR_STRUCTURAL"
# v2.1 #434 type-aware compression env override. Tri-state.
ENV_TYPE_AWARE_COMPRESSION: Final[str] = "AELFRICE_TYPE_AWARE_COMPRESSION"
# v2.1 #433 vocabulary-bridge env override. Tri-state.
ENV_VOCAB_BRIDGE: Final[str] = "AELFRICE_VOCAB_BRIDGE"
# v1.3.0 posterior-weight env override. Float-typed; "0.0" is the
# only value that fully disables (collapsing to BM25-only ordering).
# Empty / non-numeric values fall through to the next precedence
Expand Down Expand Up @@ -320,6 +328,21 @@ def _env_hrr_structural_override() -> bool | None:
return None


def _env_vocab_bridge_override() -> bool | None:
"""Return True/False if AELFRICE_VOCAB_BRIDGE is set to a recognised
truthy/falsy value, else None. Symmetric to
`_env_bm25f_override`."""
raw = os.environ.get(ENV_VOCAB_BRIDGE)
if raw is None:
return None
norm = raw.strip().lower()
if norm in _ENV_FALSY:
return False
if norm in _ENV_TRUTHY:
return True
return None


def _env_type_aware_compression_override() -> bool | None:
"""Return True/False if AELFRICE_TYPE_AWARE_COMPRESSION is set to a
recognised truthy/falsy value, else None. Symmetric to
Expand Down Expand Up @@ -762,6 +785,32 @@ def resolve_use_type_aware_compression(
return False


def resolve_use_vocab_bridge(
explicit: bool | None = None,
*,
start: Path | None = None,
) -> bool:
"""Resolve the HRR vocabulary-bridge flag (#433).

Precedence (first decisive wins):
1. AELFRICE_VOCAB_BRIDGE env var (truthy / falsy normalised).
2. Explicit `explicit` kwarg from the caller.
3. `[retrieval] use_vocab_bridge` in `.aelfrice.toml`.
4. Default: False — ships behind the flag at v2.0.0; the bench gate
(A2 in docs/feature-hrr-vocab-bridge.md) flips the default
after lab-side benchmark evidence clears.
"""
env = _env_vocab_bridge_override()
if env is not None:
return env
if explicit is not None:
return explicit
toml_value = _read_toml_flag_for(VOCAB_BRIDGE_FLAG, start)
if toml_value is not None:
return toml_value
return False


_PLACEHOLDER_WARNED: set[str] = set()


Expand Down Expand Up @@ -1448,7 +1497,7 @@ def retrieve_v2(
query: str,
budget: int = DEFAULT_TOKEN_BUDGET,
include_locked: bool = True,
use_hrr: bool = False, # noqa: ARG001
use_hrr: bool | None = None,
use_bfs: bool | None = None,
use_entity_index: bool | None = None,
l1_limit: int = DEFAULT_L1_LIMIT,
Expand All @@ -1462,6 +1511,8 @@ def retrieve_v2(
temporal_sort: bool = False,
temporal_half_life_seconds: float | None = None,
use_type_aware_compression: bool | None = None,
use_vocab_bridge: bool | None = None,
vocab_bridge_cache: VocabBridgeCache | None = None,
) -> RetrievalResult:
"""Lab-compatible retrieval wrapper for academic-suite adapters.

Expand All @@ -1471,9 +1522,21 @@ def retrieve_v2(
- `budget` (lab kwarg) maps to `token_budget` (public kwarg).
- `include_locked=False` filters out lock_level != LOCK_NONE post-retrieval
(public always returns L0 first; this wrapper drops them on demand).
- `use_hrr` is accepted but no-op at v1.3.0 — the HRR vocabulary
bridge has not yet ported. Callers can pass it for forward-compat
without conditionals.
- `use_hrr` is a deprecated alias for `use_vocab_bridge` (#433).
Lab v2.0.0 adapters that pass `use_hrr=True` route to the
vocabulary bridge; new callers should use `use_vocab_bridge`
directly. The alias survives for one minor version.
- `use_vocab_bridge` (v2.1 #433) — when True, retrieve_v2 builds
(or fetches a cached) `VocabBridge` against the store and
rewrites the query before lane fan-out. Default-OFF until the
bench gate (A2 in docs/feature-hrr-vocab-bridge.md) clears.
Original-query tokens are preserved verbatim; canonical-entity
rewrites are appended, never substituted.
- `vocab_bridge_cache` (v2.1 #433) — explicit `VocabBridgeCache`
to reuse an already-built bridge. None falls through to a
fresh `VocabBridgeCache(store)` per call. Long-running
consumers should pass an explicit cache to amortise the
build cost across queries.
- `use_bfs` (v1.3.0) maps to `retrieve()`'s `bfs_enabled` kwarg.
None falls through to the default-OFF resolution (env / TOML
/ False at v1.3.0). Setting it True opts a single retrieve_v2
Expand Down Expand Up @@ -1504,6 +1567,19 @@ def retrieve_v2(
`result.beliefs` (and stub diagnostics fields, plus the new
v1.3 `entity_hits` and `bfs_chains`).
"""
# v2.1 #433 vocabulary-bridge query rewrite. Runs before lane
# fan-out so every lane sees the widened query string. The bridge
# appends canonical-entity rewrites; the original tokens are
# preserved verbatim, so a flag-OFF call is byte-identical to the
# pre-bridge behaviour. `use_hrr` is a deprecated alias.
bridge_explicit = use_vocab_bridge
if bridge_explicit is None and use_hrr is not None:
bridge_explicit = use_hrr
if resolve_use_vocab_bridge(bridge_explicit):
cache = vocab_bridge_cache or VocabBridgeCache(store)
bridge: VocabBridge = cache.get()
query = bridge.rewrite(query)

(
out,
locked_ids_list,
Expand Down
Loading
Loading