Skip to content

[DV-14] [P2] Apply the request path scope before Graphify ranks and limits context results #574

Closed

Description

@wsdt

Priority: P2
Area: Graphify context adapter
Repository / target branch: wavect/semaprax / wavect/v090
Reviewed commit: 5428b0805fa3cf35859c843a53e30c3252ef378c
Review date: 6 October 2026

Failure and impact

Graphify accepts the context request's in field but ignores it when collecting search results and references. A request scoped to allowed returns source items from allowed-sibling and elsewhere as well. Unrelated results can consume the item limit, reduce useful context, and make source selection disagree with the user's requested area.

This is a request-scope correctness defect, not evidence of a filesystem permission escape: the provider already has project-read access. The host independently filters the configured provider scope, which may cover the whole project; it does not currently enforce the narrower scope of this individual request.

Exact source and cause

Executed reproduction

Load the unchanged production Graph, Index, and request handlers. Use three real temporary files, each defining helper, with corresponding valid graph nodes:

allowed/a.py
allowed-sibling/b.py
elsewhere/c.py

Inject only Index.ensure to return this already validated deterministic graph, then call the real search handler:

{"query": "helper", "in": "allowed", "max_items": 20}

Observed status: complete with these returned paths:

["allowed-sibling/b.py", "allowed/a.py", "elsewhere/c.py"]

Expected item paths: only allowed/a.py. Search, ranking, source reads, item creation, and envelope fitting all use production code. This is an adapter component reproduction; an actual Graphify extractor or full host workflow was not executed. The equivalent omission in references is source-confirmed and needs its own regression within this ticket. See repros/context/repro_graphify_scope.py and evidence/graphify-scope-evidence.json.

Focused fix

Apply component-aware project-relative scope matching before ranking and max_items truncation. For in: "allowed", admit the exact file path when applicable and descendants allowed/..., but not allowed-sibling/.... Scope references by the returned call-site path while preserving legitimate target resolution outside the scoped directory; restricting targets to the same directory could incorrectly remove calls to external definitions.

Add broker-side filtering by the request scope as a defensive consistency check for all external providers. Keep the configured provider scope too; both constraints must hold. A post-limit filter alone is insufficient because out-of-scope candidates could already have displaced useful in-scope items. Maintain truthful coverage and Graphify's existing non-exhaustive reference/absence semantics.

Acceptance criteria

  • Scoped search returns only items at or under the requested path, with deterministic ranking among that filtered set.
  • Scoped references filters call sites before truncation and still resolves targets defined elsewhere.
  • Sibling-prefix paths such as allowed-sibling do not match allowed.
  • A high-ranking out-of-scope item cannot consume the entire result limit and starve an in-scope result.
  • An exact file scope, directory scope, no scope, and an empty in-scope result behave consistently.
  • The broker prevents a provider returning out-of-scope items from admitting them into the final context packet.
  • Coverage remains honest; no empty result is upgraded into proof of absence.

Existing issue boundary and implementation handoff

The context/Graphify implementation predecessors include #423, #446, and #421. No retrieved issue describes this missing per-request filter. Read AGENTS.md, the context contract, and the existing Graft scope behavior as a consistency reference. Extend Graphify's current Python fixtures and the existing broker tests; avoid a new context provider API.

Activity

  1. wsdt commented on Oct 6, 2026

    @wsdt
    MemberAuthor

    Fixed in 83044ff (pushed to main). Graphify ignored in; a component-aware scope_of() now filters search nodes before ranking and the item limit and reference call sites before truncation (invalid in → SPX-HPG006), and the broker applies the request's within on every provider, forfeiting exhaustiveness on any drop. Evidence: 4 new RequestScope Python tests (all failed on the old adapter), graphify suite 77 OK, and context dv14_a_provider_item_outside_the_request_scope_is_never_admitted.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions