feat: bind shadow recall profiles to V2 surface admission decisions (#186) - #187
Open
ezutfen wants to merge 2 commits into
Open
feat: bind shadow recall profiles to V2 surface admission decisions (#186)#187ezutfen wants to merge 2 commits into
ezutfen wants to merge 2 commits into
Conversation
…186) Bind #160's governed/exploratory shadow recall packets to the exact #158 risk_aware_shadow_v1 per-surface decisions instead of reconstructing admission from review_status, disputed stay-kind logic, and the #159 Path-A projection. - admission_shadow: shared bulk V2 resolver (resolve_bulk_v2_decisions) — fresh exact evaluation + latest persisted V2 row, classified current/missing/stale/mismatched/unsupported; simulate paths share the same evaluation core and bulk #157 selection (no per-item N+1). - assessments: bulk effective #157 selection over one shared pure core. - recall_signals: fail-closed V2 surface gate (recall-admission-v2) with full safe binding block; local rules (lifecycle, #159 blocked/stale) remain withhold-only defense in depth. - recall: live-proposal corpus predicate before the bounded HNSW window; bounded content-free admission diagnostics + resolution summary. - recall_shadow/route: recall-shadow-compare-v2 additive payload. - ADR-160 supplement; shadow-only boundary unchanged (CERTIFIED_SERVING_PROFILES == {legacy}).
…l withholds (#186) Review corrections to the #186 V2 surface admission binding, with no change to the shadow-only serving boundary: - Blocker 1: V2-bound profiles dispatch through the surface gate before the profile-generic #159 pre-check, so a local blocked/strict-stale withhold keeps the resolved V2 binding (resolution status, exact surface decision, persisted/fresh identity) instead of reading as missing; local precedence for the decision and primary reason code is unchanged, and the withheld result also carries the #159 assessment identity. - Blocker 2: withheld-candidate admission diagnostics now embed the same full safe v2 binding block admitted items carry (persisted + fresh identity, exact surface decision, bounded state/code sets), reusing the single binding builder. - Blocker 3: V2SurfaceBinding splits persisted-row identity (read from the row's own columns) from the fresh evaluation's identity; stale hashes, mismatched artifact digests, and unsupported schemas stay individually visible instead of being collapsed into fresh fields. - Minor: resolve_bulk_v2_decisions reports the number of queries actually executed (the bulk #157 selection counts its early returns) rather than a flat ceiling; constant in window size either way.
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 #186 (ENG-RECALL-003B). Parent #160, epic #153. Depends on #158/#159/#160 (PRs #183/#182/#184, all merged).
Summary
Bind #160's governed/exploratory shadow recall packets to the exact #158
risk_aware_shadow_v1per-surface decisions, instead of reconstructing candidate admission fromreview_status, disputed stay-kind logic, and the #159 Path-A projection. Shadow-only: no change to production recall serving authority, promotion authority, orCERTIFIED_SERVING_PROFILES.Architecture
engram/admission_shadow.py:resolve_bulk_v2_decisions) — owned by the ENG-PROMOTION-003C — Replace the universal 72-hour gate with versioned risk-based admission profiles #158 module so the simulator, the operator simulate surfaces, and ENG-RECALL-003 — Separate relevance, utility, and epistemic trust in recall admission and ranking #160 recall cannot drift on "what is the effective V2 decision?". Evaluates the exact decision fresh for the whole window (bulk promotion support + bulk ENG-CLASSIFY-003 — Separate retention value from epistemic confidence and support versioned reassessment #157 selection via a new shared pure selection core + one latest-row lookup) and resolves the latest persisted V2 shadow row against it. Query count is constant at 7 regardless of window size; no provider calls; reads only.RecallProfileSpec.v2_surface): governed →semantic_governed, exploratory →semantic_exploratory— neverstartup, neverhighest_admission_tier. Because the ENG-PROMOTION-003C — Replace the universal 72-hour gate with versioned risk-based admission profiles #158 policy's domain is live proposals (not_live→ blocked on every surface), the candidate corpus windows are now the live-proposal SQL predicate (proposed AND valid_to IS NULL AND superseded_by IS NULL AND conflict IS DISTINCT FROM 'unresolved') applied before the bounded HNSW window;review_status='active'is no longer a positive admission source anywhere on the candidate path.current | missing | stale | mismatched | unsupported, canonical ENG-PROMOTION-003D — Persist promotion assessments and expose next-action state #159-style vocabulary): onlycurrent(row'sdecision_hash== fresh evaluation — the fresh evaluation is the verification, no projection pointer trusted) carries positive authority; each other status withholds with its own reason code (v2_decision_*).stalecovers input-digest drift (state, effective ENG-CLASSIFY-003 — Separate retention value from epistemic confidence and support versioned reassessment #157 selection, content identity, time-window crossings).engram/recall_signals.py,recall-admission-v2): an item enters a candidate packet only when the exact surface decision isallowunder acurrentresolution;withhold/review_required/blocked/unknownare consumed as-is. Recall-local rules (ENG-PROMOTION-003D — Persist promotion assessments and expose next-action state #159blocked/strict-stale, lifecycle) remain withhold-only defense in depth — a V2 allow can never widen tenant/RLS/workspace/visibility boundaries; local-vs-V2 disagreements surface as bounded content-freeadmission_diagnostics(id, codes, resolution status,gates_disagree).recall-shadow-compare-v2): per-itemadmission.v2binding block (assessment id, schema version, policy version + artifact digest, decision hash, resolution status, exact surface decision, risk/epistemic/retention state, effective ENG-CLASSIFY-003 — Separate retention value from epistemic confidence and support versioned reassessment #157 refs, window times, bounded code sets — identity and codes only, no content/provider output) plus per-packet diagnostics and av2_resolutionsummary with per-status counts and query count.Shadow-only boundary — confirmed unchanged
CERTIFIED_SERVING_PROFILESremains{"legacy"}(test-pinned).POST /v1/recallremains legacy-only; requesting governed/exploratory still 422.recall_logs, no exposure counters, no promotion/review/evidence side effects, no shadow-current projections (test-pinned, incl. capture-disabled rollback reads).tenant_config.recall_profile_shadow_enabledstill gate the surface; explicit workspace denial still yields no broader fallback.Verification
make check— lint + strict typecheck + root suite green (12 local failures are byte-identical to unmodifiedmainin this environment: missingengram_client/engram_hooksworkspace installs + subprocess tests crashing in the local AppImage python).make compose-ci— fully green: 3838 passed, 35 skipped, 0 failed against real PostgreSQL + pgvector under the non-owner app role.Documentation
Non-goals honored
No #161 corroboration lane, no evidence-root redesign, no positive-feedback admission, no #162 certification run, no production governed/exploratory rollout, no signal-aware expansion or final packing work. #161/#162 production enablement is not authorized by this PR.