Skip to content

fix: isolate historical evidence recall by message branch - #573

Merged
chenyme merged 1 commit into
devfrom
rag
Aug 5, 2026
Merged

fix: isolate historical evidence recall by message branch#573
chenyme merged 1 commit into
devfrom
rag

Conversation

@chenyme

@chenyme chenyme commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #559.

Fixes historical evidence recall leaking across conversation branches after retrying or editing a message.

This change:

  • Introduces HistoricalMessageScope, based on the immutable parent_message_id ancestor chain.
  • Encapsulates the conversation, user, current leaf message, and snapshot boundary in a single historical recall scope.
  • Resolves the active branch in the database using a recursive CTE, avoiding large IN parameter lists.
  • Filters context artifacts by branch before applying LIMIT, preventing newer sibling evidence from occupying recall slots.
  • Filters semantic recall candidates before vector Top-K selection:
    • SQLite constrains the vector query to active-branch messages.
    • PostgreSQL materializes active-branch chunks before exact similarity sorting, preventing IVFFlat candidates from sibling branches from occupying the result set.
  • Excludes evidence covered by the active context snapshot.
  • Fails closed for invalid snapshot boundaries, cross-user parent chains, and cyclic parent chains.
  • Associates newly generated prompt, tool-call, and summary artifacts with the corresponding assistant message.
  • Backfills legacy artifact ownership:
    • Records are migrated only when one unique assistant message exists for the same conversation, user, and run.
    • Ambiguous or unverifiable records remain unchanged.
    • The backfill is idempotent.
  • Validates assistant-message, conversation, user, and run ownership when reading artifacts.
  • Rejects new artifacts with incomplete ownership fields and normalizes run IDs before persistence.
  • Adds coverage for long branches, first-turn conversations, retries, edits, snapshot boundaries, cross-user chains, cyclic chains, legacy backfill, and vector Top-K ordering.
  • Ensures the new migration test properly closes its SQLite connection for stable repeated and shuffled execution.

Change type

  • Bug fix
  • Feature
  • Documentation
  • Refactor
  • Configuration / deployment
  • Security hardening
  • Other

Affected areas

  • Frontend / UI
  • Backend / API
  • Authentication / authorization
  • Conversations / streaming
  • Files / RAG / extraction
  • Model routing / providers
  • MCP / tools
  • Billing / payments
  • Admin console
  • Deployment / Docker / configuration
  • Documentation

Verification

  • GOCACHE=/private/tmp/deeix-559-full-cache go test ./...
  • GOCACHE=/private/tmp/deeix-559-final-vet-cache go vet ./...
  • Relevant branch-isolation tests with -shuffle=on -count=5
  • Relevant conversation, repository, schema, SQLite vector, and migration tests with go test -race
  • pnpm api:check
  • git diff --check
  • The PostgreSQL integration test compiles and is gated by DEEIX_TEST_DATABASE_DSN; it was skipped locally because no valid test DSN was configured.

Screenshots, API examples, or logs

No frontend or public API changes.

The regression is covered by tests for:

  • Retrying or editing the first turn without recalling evidence from the abandoned branch.
  • Retrying a later turn while preserving evidence from valid ancestor turns.
  • Filtering sibling evidence before artifact LIMIT and vector Top-K.
  • Valid and invalid snapshot boundaries.
  • Branches longer than typical SQL parameter limits.
  • Cross-user parent pointers and cyclic parent chains.
  • Legacy artifact ownership backfill.

Configuration, migration, and compatibility notes

  • No new configuration fields or environment variables.
  • No database schema changes or manual migration steps.
  • Existing context artifacts are repaired automatically during startup migration only when a unique assistant owner can be identified within the same conversation, user, and run.
  • Ambiguous legacy records are not guessed or destructively rewritten. They remain excluded from branch-scoped recall unless their ownership is valid.
  • The backfill is idempotent and safe across repeated application startups.
  • SQLite and PostgreSQL use dialect-appropriate branch-scoped vector queries.
  • No public API or generated Swagger contract changes.
  • Existing linear conversation behavior is preserved. Only cross-branch evidence leakage is removed.

Documentation

  • Documentation is not needed for this change.
  • Documentation was updated.
  • Documentation still needs to be updated.

Security and privacy

  • No secrets, tokens, credentials, local config, or personal data are included.
  • User data access remains scoped by authenticated user context unless an admin-only path explicitly requires broader access.
  • Security-sensitive behavior was reviewed, including authentication, authorization, provider routing, file processing, billing, and admin APIs where relevant.

Historical evidence queries now enforce conversation, user, message-branch, and run ownership together. Invalid, ambiguous, cross-user, or cross-branch evidence fails closed and is not injected into model context.

Checklist

  • I searched existing issues and pull requests.
  • Changes are focused and do not include unrelated refactors.
  • Tests or static verification were run where practical.
  • User-facing behavior, deployment steps, API contracts, or configuration changes are documented.
  • Generated artifacts are included only when this project explicitly requires them.
  • Caches, build output, .pyc files, .env files, and local storage data are not committed.

@chenyme chenyme self-assigned this Aug 5, 2026
@chenyme
chenyme merged commit 44518e4 into dev Aug 5, 2026
11 checks passed
@chenyme
chenyme deleted the rag branch August 5, 2026 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: 历史证据召回未按分支隔离,重试后旧分支工具结果泄漏到新分支

1 participant