feat: add conflict-preserving, diversity-aware candidate packing (#192) - #193
Merged
Conversation
Replace the governed/exploratory shadow profiles' rank-then-truncate selection with a versioned, deterministic packing contract (recall-packing-v1) that runs strictly after admission (#186), admission- first relationship expansion (#190), and the separated relevance/utility ranking: - mechanically-known redundancy groups (explicit derived_from edges and exact content_hash duplicate identity only — similarity is never root identity) yield to distinct context under bounded budgets, with deterministic representatives and sibling fill; - explicit conflicts (conflicts_with_item_id linkage and contradicts edges, both endpoints admitted candidates) create co-pack obligations under the same hard item/byte/token budgets; budget-impossible co-packs are recorded (conflict_counterpart_budget), never silently resolved; withheld/inaccessible counterparts are neither resurrected nor identity-leaked; - packing mutates nothing: relevance/utility/admission/evidence/epistemic state are untouched; only an additive per-item packing_reason and a bounded packet-level packing summary are added (shadow surface only); the legacy packet stays byte-for-byte unchanged and production remains legacy-only. Packing relations load in one bulk edge query scoped to both endpoints inside the admitted set — no provider call, no N+1, no graph walk, no second V2 evaluation. ADR-160 records the supplement.
…ges (#192) Merge-blocker correction for recall-packing-v1: bare content_hash equality is not mechanically-known shared-root identity. The durable dedup identity is scoped over (tenant, workspace, principal, content_hash), so two admitted rows may legally share a hash across scope boundaries with no derivation relation; equal canonical content proves equal canonicalized text only. Unknown root stays unknown (#161 owns evidence-root semantics). - remove content_hash from PackCandidate and _known_root_groups(); the only v1 root signal is explicit derived_from connectivity (transitive) - rewrite hash-family packer tests as explicit-derivation families; add input-surface pin and transitive-chain composition test - add same-hash/different-scope negative regression: identical hash, two workspaces, no derivation -> both selected by rank, distinct item omitted by budget alone, never redundant_known_root - link the direct + tunnel-expanded cross-workspace family with an explicit derived_from edge instead of a shared rewritten hash - ADR-160/module doctrine: canonical content equality is not provenance; idx_memitems_dedup is scoped duplicate prevention, not a root assertion Conflict adjacency, phases, budgets, reasons, accounting, rendered ordering, and the recall-packing-v1 contract identity are unchanged.
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.
Closes #192 (ENG-RECALL-003E). Parent #160, epic #153. Baseline
c1d5f24(post #190/#191).What
Replaces the governed/exploratory shadow profiles' rank-then-truncate selection with one versioned, deterministic packing contract —
recall-packing-v1(engram/recall_packing.py) — operating strictly after admission (#186), admission-first relationship expansion (#190), and separated relevance/utility ranking, and only inside the read-only shadow comparison surface:Algorithm (pure, in-memory, phased — no global packing score)
derived_fromedges between admitted candidates. Canonical content equality (identicalcontent_hash) proves only equal canonicalized text — the write-path dedup index (idx_memitems_dedup, scoped over tenant/workspace/principal/hash) is scoped duplicate prevention, not a global root assertion — so it is not a root signal and never groups. Similarity is never root identity either; unknown root stays unknown and is never coerced to independent or redundant (ENG-EVIDENCE-001 — Evidence-root-aware corroboration and usefulness lane #161 keeps sole ownership of corroboration).ranked); selecting one side of an explicit conflict immediately attempts to co-pack its admitted counterpart (conflict_pair_preserved) ahead of lower-ranked redundancy, under the same hard budgets.diversity_fill) — siblings are crowd-out protected, not forbidden.len(content.encode())bytes,max(1, bytes//4)tokens), same skip-not-break discipline — never exceeded, deterministic boundaries.selected + Σ omitted == admitted count; omission reasonsconflict_counterpart_budget>redundant_known_root>budget; packet-levelpackingsummary is counts only (version, selected count, preserved conflict-pair count, omission counts) — no rejected content, no counterpart ids.packing_reason; relevance/utility/admission/evidence/epistemic/risk/warning codes/relationship blocks are not packer inputs it can rewrite.Merge-blocker correction (this push):
content_hashis not a root signalReview correctly flagged that bare
content_hashequality was treated as mechanically-known shared-root identity. That is too broad: Engram's durable duplicate identity is scoped over(tenant_id, workspace_id, principal_id, content_hash), so two admitted rows may legally share a hash across workspace/principal scope with no derivation relationship — equal canonical content proves the same canonicalized proposition text, not same evidence root, provenance, or a copied/derived relationship. #192 requires unknown root to remain unknown and leaves evidence-root-aware corroboration/independence to #161.Correction (selection behavior, phases, conflicts, budgets, reasons, accounting, ordering, and the
recall-packing-v1contract identity are unchanged):content_hashremoved fromPackCandidateentirely — content identity cannot even reach the packer (pinned bytest_packer_input_surface_excludes_content_identity)._known_root_groups()now unions only over explicitderived_fromedges (transitively through chains). No substitute heuristic.test_same_hash_different_scope_is_not_a_known_root: two admitted candidates, identical durable hash, different workspaces, no derivation — both selected by rank under budget 2, the distinct item omitted bybudgetalone,redundant_known_rootabsent.derived_fromedge (same direct+expanded scenario, genuine durable relation).idx_memitems_dedupnever described as proving cross-scope duplicate/root identity.Before/after evidence (live packets, item budget 2)
derived_from) + distinct[alpha one, alpha two]— family crowd-out[alpha one, distinct fact],omitted: {redundant_known_root: 2}[alpha, contra],conflict_pairs_preserved: 1, sibling deferredcontent_hash, different workspace, no derivation[A, B]both by rank,omitted: {budget: 1}— root stays unknown, neverredundant_known_rootomitted: {conflict_counterpart_budget: 1, redundant_known_root: 1}— bounded and honest, never a silent resolutionBoundedness / security
Rollout boundary (unchanged)
Legacy packet is byte-for-byte unchanged (
packing: None, nopacking_reasonkeys,/v1/recalloutput identical);CERTIFIED_SERVING_PROFILES == {"legacy"}; requesting a candidate profile on ordinary recall still 422s; no MCP selection; no #161 corroboration, no Context Ledger receipts, no #162 certification/cutover.Tests
tests/test_recall_packing.py— 32 tests covering the issue's full matrix: known-root diversity via explicit derivation (1–5) plus transitive derivation chains and the packer input-surface pin, conflict preservation (6–11), direct+expanded integration including the explicit-derivation cross-workspace family and the same-hash/different-scope negative regression (12–14), budget boundaries + reconciliation (15–18), semantic separation (19–22), security/perf/compat (23–30). DB-backed tests skip without PostgreSQL, mirroringtests/test_recall_profile_semantic.py.Validation
tests/test_recall_packing.py32 passed against live PostgreSQL 16 + pgvector;tests/test_recall_profile_semantic.py+tests/test_scope_completeness.py64 passed.make check— lint + strict mypy green; root suite green except two portal failures (test_rotation_http_replay_status_and_credential_cutover,test_rotation_and_termination_functions_are_owner_only) reproduced identically on the unmodified PR head (environment-only; they need the full CI compose env).make compose-ci— green against real PostgreSQL 16 + pgvector under the non-owner app role.Docs
ADR-160 supplement records the #192 contract (packing after admission+ranking; mechanically-known roots = explicit
derived_fromonly, canonical content equality is not provenance; conflicts as representation obligations; hard budgets; no mutation; #161 ownership preserved) and the landed packing follow-ups are removed from Known limitations.Post-merge follow-up (needs the merge SHA): update #160 progress with landed PR/head/merge SHA and remaining slices.