feat(edge_rerank): edge-type-keyed rerank consumer (#421) - #429
Conversation
Reviewer's GuideIntroduces a new edge-type-keyed rerank consumer that demotes BFS results based on incoming marker edges (notably POTENTIALLY_STALE), wires it into the BFS/graph model contracts, and adds tests, corpus schema, and docs plus a bench gate to enforce ≥1pp@k stale-drop. Sequence diagram for BFS expansion with edge-type-keyed reranksequenceDiagram
actor Caller
participant BFS as expand_bfs
participant Rerank as apply_edge_type_rerank
participant Store as MemoryStore
Caller->>BFS: expand_bfs(seeds)
BFS-->>Caller: list ScoredHop hops
Caller->>Rerank: apply_edge_type_rerank(hops, Store, penalties)
loop for each hop in hops
Rerank->>Store: edges_to(hop.belief.id)
Store-->>Rerank: list Edge incoming
Rerank->>Rerank: select firing edge types
Rerank->>Rerank: multiply hop.score by penalties
end
Rerank->>Rerank: sort rescored hops by (-score, belief.id)
Rerank-->>Caller: list ScoredHop rescored_hops
Class diagram for edge-type-keyed rerank consumer and MemoryStore updatesclassDiagram
class MemoryStore {
+edges_from(src: str) list~Edge~
+edges_to(dst: str) list~Edge~
+iter_all_edges() Iterator~Edge~
}
class Edge {
+id: str
+src: str
+dst: str
+type: str
}
class ScoredHop {
+belief: Belief
+score: float
+depth: int
+path: list~Edge~
}
class Belief {
+id: str
}
class edge_rerank_module {
+DEFAULT_STALE_PENALTY: float
+EDGE_TYPE_PENALTIES_DEFAULT: Mapping~str, float~
+apply_edge_type_rerank(hops: list~ScoredHop~, store: MemoryStore, penalties: Mapping~str, float~)
}
class models_constants {
+EDGE_POTENTIALLY_STALE: str
}
MemoryStore --> Edge : returns
ScoredHop --> Belief : belief
ScoredHop --> Edge : path
edge_rerank_module --> ScoredHop : rescored
edge_rerank_module --> MemoryStore : uses edges_to
edge_rerank_module --> models_constants : uses EDGE_POTENTIALLY_STALE
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The rerank path currently performs an
edges_toquery per hop, which is effectively an N+1 pattern; if this will ever run on large hop lists, consider a batchededges_to_many(dst_ids)API or prefetch to avoid repeated single-row scans. apply_edge_type_rerankis hard-wired toMemoryStore; if you plan to plug in other store backends (or mocks), consider typing this parameter against a minimal protocol (e.g.,Protocolwithedges_to) to decouple the reranker from the concrete store implementation.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The rerank path currently performs an `edges_to` query per hop, which is effectively an N+1 pattern; if this will ever run on large hop lists, consider a batched `edges_to_many(dst_ids)` API or prefetch to avoid repeated single-row scans.
- `apply_edge_type_rerank` is hard-wired to `MemoryStore`; if you plan to plug in other store backends (or mocks), consider typing this parameter against a minimal protocol (e.g., `Protocol` with `edges_to`) to decouple the reranker from the concrete store implementation.
## Individual Comments
### Comment 1
<location path="docs/edge_rerank.md" line_range="24" />
<code_context>
+caller (e.g., retrieve_with_tiers token-budget pack)
+```
+
+The pass is pure: same `(hops, store, penalties)` produces
+byte-identical output. It uses `MemoryStore.edges_to(dst)` to query
+incoming edges per surfaced belief.
</code_context>
<issue_to_address>
**nitpick (typo):** Clarify grammar in the description of the pure pass.
Consider rephrasing "same `(hops, store, penalties)` produces" to something like "The pass is pure: the same `(hops, store, penalties)` produces byte-identical output" or "The pass is pure: the same inputs produce byte-identical output" for smoother grammar.
```suggestion
The pass is pure: the same `(hops, store, penalties)` produces
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| caller (e.g., retrieve_with_tiers token-budget pack) | ||
| ``` | ||
|
|
||
| The pass is pure: same `(hops, store, penalties)` produces |
There was a problem hiding this comment.
nitpick (typo): Clarify grammar in the description of the pure pass.
Consider rephrasing "same (hops, store, penalties) produces" to something like "The pass is pure: the same (hops, store, penalties) produces byte-identical output" or "The pass is pure: the same inputs produce byte-identical output" for smoother grammar.
| The pass is pure: same `(hops, store, penalties)` produces | |
| The pass is pure: the same `(hops, store, penalties)` produces |
|
[claim:review:Gylf:2026-05-05T16:33:16Z] |
|
This PR is now behind Auto-rebase was removed because the bot has no signing key; rebasing as the bot strips author signatures and the |
|
LGTM on code, but REBASE-NEEDED — main advanced when #425 landed ( Inspection results:
Action to land:
Releasing review claim. — Gylf |
|
[release:review:Gylf:2026-05-05T16:35:04Z] |
Tag-shaped edge distinct from EDGE_TYPES / EDGE_VALENCE. Carries no propagation valence; consumed by the rerank pass in aelfrice.edge_rerank (this issue), produced by aelf doctor (#387). Skip-during-BFS contract lands in the next commit.
Symmetric companion to edges_from. Consumed by the edge-type-keyed rerank pass to detect marker edges (POTENTIALLY_STALE) targeting a surfaced belief; the rerank pass needs to ask 'does any incoming edge to this dst tag it as stale?' rather than walking outbound.
Pure-function module that takes BFS hits, examines each surfaced belief's incoming edges via store.edges_to, and applies a configurable multiplicative penalty per matching edge type. POTENTIALLY_STALE keyed by default at 0.5; multi-edge-type composition is multiplicative. Returns a new ScoredHop list sorted by (-score, belief.id) — the same tie-break used by expand_bfs so the two passes compose without order surprises. Acceptance #1, #2, #4 of the issue. Tests + bench-gate stub follow.
…on (#421) 11 unit tests cover the consumer's full contract: empty-hops/empty-cfg no-ops, default POTENTIALLY_STALE demotion, set-based 'fires once per type', multi-edge multiplicative composition, isolated-belief identity, tie-break sort, custom-cfg override, zero-penalty zeroing, default-cfg pin, byte-identical determinism. Bench-gate stub at tests/bench_gate/test_edge_rerank_potentially_stale.py implements #421 acceptance #3 / #387 acceptance #3: ≥1pp@k drop in stale-tagged retrieval after the rerank pass. Skips on no AELFRICE_CORPUS_ROOT or <30 non-seed rows. New corpus module 'bfs_potentially_stale' registered in tests/test_corpus_schema.py with the same graded shape as the Track A fixtures plus the 'stale_ids' subset field.
6ed47c3 to
d3fd1db
Compare
Closes #421. Prerequisite for #387 POTENTIALLY_STALE demotion.
Summary
aelfrice.edge_rerank.apply_edge_type_rerank— pure-function rerank consumer that takes BFS hits + per-edge-type penalty config and applies multiplicative demotion based on incoming edge types of the surfaced belief.BFS_EDGE_WEIGHTS[POTENTIALLY_STALE] = 0.0pinned explicitly (skip-during-BFS contract per feat(retrieval): edge-type-keyed rerank consumer — prerequisite for #387 POTENTIALLY_STALE demotion #421 acceptance feat: add Belief/Edge dataclasses and config module #4). The demotion happens in the rerank pass, not in BFS expansion.EDGE_POTENTIALLY_STALEmarker constant. Deliberately NOT inEDGE_TYPES/EDGE_VALENCE— it's a tag, not a relational edge.MemoryStore.edges_to(dst)symmetric toedges_from.tests/test_edge_rerank.py+ bench-gate stub intests/bench_gate/test_edge_rerank_potentially_stale.pyfor [v2.0 / Track A] addPOTENTIALLY_STALEedge type — bench-gated +5pp BFS multi-hop #387's ≥1pp@k drop gate (skips on noAELFRICE_CORPUS_ROOT).bfs_potentially_staleregistered intests/test_corpus_schema.py+ README.docs/edge_rerank.md.Acceptance map (issue #421)
POTENTIALLY_STALEkeyed in penalty config; default penalty0.5.POTENTIALLY_STALEedge type — bench-gated +5pp BFS multi-hop #387's ≥1pp@k drop gate. Skip-on-no-corpus.BFS_EDGE_WEIGHTS[POTENTIALLY_STALE] = 0.0pinned (contract reviewable, not implicit).Producer is out of scope
POTENTIALLY_STALEedge-writer (aelf doctor) is #387 — closes against this PR's substrate.Test plan
uv run pytest tests/test_edge_rerank.py -v— 11 passeduv run pytest tests/test_bfs_multihop.py tests/test_corpus_schema.py -q— passes (BFS spec-pin updated for new entry)uv run pytest --ignore=tests/bench_gate -q— 2460 passed, 23 skipped, no regressionsuv run pytest tests/bench_gate/test_edge_rerank_potentially_stale.py— skips cleanly without corpusAELFRICE_CORPUS_ROOT=... uv run pytest tests/bench_gate/test_edge_rerank_potentially_stale.py— runs oncebfs_potentially_stale/corpus is populated. Will gate [v2.0 / Track A] addPOTENTIALLY_STALEedge type — bench-gated +5pp BFS multi-hop #387 closure.Sequence
This PR will stack behind #425's soak-gate timer (same
consecutive-green ≥ 7dReplay Soak Gate blocker).Summary by Sourcery
Introduce an edge-type-keyed rerank consumer that demotes POTENTIALLY_STALE-tagged beliefs after BFS and wire it into the retrieval pipeline with tests, corpus schema, and documentation.
New Features:
Enhancements:
Documentation:
Tests: