fix: rebuild block dedupes by content_hash (#281 partial) - #293
Conversation
|
[claim:review:Gylf:2026-04-29T02:21:58Z] |
|
Sending back. PR #283 (merged earlier today) added a UNIQUE constraint on
Recommend: rebase on main, drop the cross-id hash collision fixtures, keep the rebuild-side |
|
[release:review:Gylf:2026-04-29T02:22:38Z] |
|
[claim:review:Setr:2026-04-29T02:28:08Z] |
|
Review: substantive test failure beyond the rebase, both new tests in The dedup logic itself in
Option 2 is closer to the intent (output-stage mask). Option 1 is closer to integration coverage. Either is fine; both also need a rebase since the branch is BEHIND main. Holding merge. Releasing review claim. |
|
[release:review:Setr:2026-04-29T02:28:53Z] |
## Summary Single-doc index for the open-issue tree. Sorts everything in `gh issue list --state open` into five waves with explicit deps, soft-deps, and cross-cutting hazards. Goal: prevent the rework patterns that already bit us (#293's tests dying on #283's UNIQUE constraint, #256 stuck on author rebase after multiple PRs landed on `store.py`, etc.). Five waves: - **Wave 0** — close-out. Seven stale items that should walk to zero before new work starts (#223, #254, #281 re-scope, #286 → tracker, #287 dup, #280, #288 implementation tail). - **Wave 1** — rebuild redesign (#288, #289, #290, #291). All four spec memos in flight; ratify all four before opening any implementation PR. Implementations must sequence (`context_rebuilder.py` is a merge-conflict spot). - **Wave 2** — phantom-prereqs T1→T2→T3 (#191/#256 stuck on rebase; #192 blocks on T2). - **Wave 3** — v2.0 substrate decision tree. #196 gates everything posterior-related. Bench-gated items (#197/#198/#199/#201/#229) wait on #288's harness producing precision/recall numbers. - **Wave 4** — v2.x materialization (#262 → #264 → #265). Sequential, must not parallelise. - **Wave 5** — long-tail retrieval / research (#154, #153). Hold; #154 refactor would rework #289–#291. Plus five cross-cutting hazards on the wall: `context_rebuilder.py` and `store.py` as merge-conflict spots; the #283 UNIQUE constraint test pattern; calibration-data bench-gate; substrate ratification before #290 implementation. ## Decision asks Bottom of the doc — operator stamping queue (5 items) that unblocks Wave 1 implementation in sequence. ## Test plan - [x] All open issues from `gh issue list` accounted for - [x] All in-flight PRs cross-referenced in the spec / impl index tables - [x] Discretion grep clean - [ ] Operator review: confirm wave assignments + hazards list
rebuild_v14 packed beliefs by id only, so 10 ids sharing one content_hash all surfaced — the symptom in #281. Track a seen_hashes set seeded from locked and skip session/L1 hits already covered. Locked wins on collision. Two regression tests: 10-way dup collapses to 1; locked takes precedence over an L1 hit with the same content_hash.
038930f to
4a8baed
Compare
|
Rebased on main (resolves BEHIND state) and reworked the tests so they don't violate the UNIQUE(content_hash) constraint that landed in #283. The dedup loop is now exercised by monkeypatching |
|
[claim:review:Setr:2026-04-29T03:07:19Z] |
|
[release:review:Setr:2026-04-29T03:08:10Z] |
Summary
Partial fix for #281: surface-level content_hash dedup in
rebuild_v14. Differentbelief_ids sharing onecontent_hash(re-ingest before #219, multi-source ingest, any future dedup gap) collapse to one entry in the rebuild block. Locked beliefs win on collision.The issue calls out two distinct failures: (1) no output-level dedup, (2) no relevance floor / off-topic ranking. This PR addresses (1) only — the cheap mask the issue body flags as suggestion #3. Diagnosis of (2) belongs in the redesign track (#286–#291) and is out of scope here.
What changed
src/aelfrice/context_rebuilder.py: trackseen_hasheswhile packing the v1.4 rebuild output. Locked seeds it; session-scoped and L2.5/L1 hits skip on collision.tests/test_context_rebuilder_hook.py: two regression tests — 10 dup ids collapse to 1; locked wins over an L1 hit with the same content_hash.Test plan
uv run pytest tests/ -q→ 1835 passed, 8 skipped on 3.13.pytest -k "281 or ac1"→ 4 passed.Closes #281 partially. Leaves the relevance-floor / ranking-redesign half tracked under #286.