Skip to content

[search] recall sessions do not pin read_scopes — a refine with different scopes merges other tenants' results into the session, and recall_drill re-checks nothing #110

Description

@devinmlowe

Evidence

src/_core/search/session.ts:42-52 RecallSession has no scope field; SessionStore.create (session.ts:76-99) stores query, results, budgets only. src/interfaces/shared/search.ts:195-235 refines an existing session with the scopes of the current call:

const response = await searchMultiSource(db, {
  query: params.query, sources, mode: "hybrid", budget: remainingBudget,
  scopes: params.scopes,   // from this call, not the session
}, config);
store.addResults(params.sessionId, response.results, params.query);

drillRecallResult (search.ts:268-297) takes sessionId + resultIndex and returns the stored result with no scope check at all. server.ts:1568-1578 (recall_session) resolves scopes per call via resolveCallScoping(process.env, params); recall_drill (server.ts:1599) passes none.

Mechanism

Sessions live in one process-wide SessionStore per worker (session.ts:203), keyed by a random UUID, shared by every client of the HTTP daemon. Two drifts follow:

  1. A session opened with read_scopes: ["hermes:career"] and refined with read_scopes omitted (env default → all scopes on the daemon) merges results from every tenant into the same session; the caller's later recall_drill then serves content it never asked to see.
  2. Any client that learns another tenant's session_id can recall_drill its results — no scope is re-checked. (Low probability: UUIDs are random; but the check is free.)

Suggested fix

Pin scopes on the session: add scopes?: string[] to RecallSession, set it in createOrRefineRecallSession on create, and on refine use session.scopes instead of params.scopes (or throw when the caller supplies a different set). Optionally re-check scopeVisible(result.metadata.scope, session.scopes) in drillRecallResult.

Related: #25, ADR-010, Phase 6 RLM.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: P2Soon: correctness gaps and small fixes with clear value

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions