Skip to content

feat: add depth parameter - #200

Merged
RonsenbergVI merged 6 commits into
mainfrom
chore/add-depth-parameter
Aug 22, 2026
Merged

feat: add depth parameter#200
RonsenbergVI merged 6 commits into
mainfrom
chore/add-depth-parameter

Conversation

@RonsenbergVI

@RonsenbergVI RonsenbergVI commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Pull Request

Type of change

  • Bug fix
  • New feature
  • Refactor / internal cleanup
  • Docs
  • Other:

Description of the changes

Adds depth parameter to graph search:

  • depth 0: BM25 search
  • depth 1: precision-favouring graph search
  • depth 2: recall-favouring graph search

depth:1 vs depth:2, precisely

A recall's text/vector channels match a seed set $S$, each seed $s$ carrying its fused seed mass $m(s)$ (raw BM25 + vector units). The traversal reaches the anchors (topic and entity vertices) adjacent to each seed. For an anchor $a$ with degree $d(a)$, write

$$M(a) = \sum_{s \in S,\ s \sim a} m(s)$$

for the mass $a$ observes: the summed seed mass of every seed adjacent to it. With $T$ the set of every anchor any seed touched, both lanes fit the same null model. One background rate, the mass-per-edge a uniform smear over the touched neighbourhood would predict:

$$b = \frac{\sum_{a \in T} M(a)}{\sum_{a \in T} d(a)}$$

so $d(a),b$ is $a$'s fair share: what an anchor of its size observes by chance. Admission happens after $b$ is fixed, so $b$ is identical in both lanes.

An anchor transmits to its members iff its observed mass clears the lane's admission bar:

$$M(a) > \theta, d(a), b, \qquad \theta = \begin{cases} 2 & \texttt{depth:1}\ 1 & \texttt{depth:2} \end{cases}$$

($\theta$ is depthOneAdmission). A candidate fact $f$ then scores

$$\mathrm{score}_\theta(f) ;=; m(f) ;+; \alpha^2 !!\sum_{\substack{a \sim f\ M(a) > \theta d(a) b}}!! \Big[, M(a) - m(f) - d(a),b ,\Big]_+,, \qquad \alpha = \tfrac12$$

The hinge inside the sum is the same in both lanes: plain fair share subtracted, the candidate' own mass excluded so a fact never funds its own boost. The only thing $\theta$ changes is which anchors appear in the sum.

Let $\rho(a) = M(a)/(d(a),b)$ be an anchor's excess ratio, how many times its null expectation it observed. Then:

  • depth:2 admit any surplus at all: $\rho(a) > 1$.
  • depth:1 admits only anchors at more than twice chance: $\rho(a) > 2$
    equivalently, anchors whose unexplained mass $M(a) - d(a)b$ exceeds their
    explained mass $d(a)b$.
  • The lanes disagree exactly on the marginal band $1 < \rho(a) \le 2$:

$$\mathrm{score}_2(f) - \mathrm{score}_1(f) ;=; \alpha^2 !!\sum_{\substack{a \sim f\ 1 < \rho(a) \le 2}}!! \big[ M(a) - m(f) - d(a)b \big]_+ ;\ge; 0$$

Three consequences fall out:

  • Nesting. The depth-1 admitted set is a subset of the depth-2 set, so depth 1's graph-reached candidates are a subset of depth 2's and $\mathrm{score}_1(f) \le \mathrm{score}_2(f)$ pointwise. Depth 2 is the recall ceiling; everything it adds over depth 1 is funded by marginal ($\rho \le 2$) evidence — which is exactly why 1 is the precision lane and 2 the max-recall lane.
  • The BM25 floor holds in every lane. Transmission only adds: $\mathrm{score}(f) \ge m(f)$ always. depth:0 is that floor exactly. The traversal is skipped and $\mathrm{score}(f) = m(f)$.
  • Hub silence is lane-independent, and depth 1 is cheaper. An anchor at or below fair share transmits in neither lane and is skipped in $O(1)$ without enumerating its members; depth 1 extends that $O(1)$ skip to the marginal band, so it also expands strictly fewer members on dense graphs.

Both lanees are the same single anchor-mediated round, depth: selects an admission bar, it does not iterate. A second round would re-observe the first round's concentrated mass through sibling anchors and collapse recall, which is why depth:3+ is rejected at parse time rather than silently answered as 2.

Motivation for the changes

Allowing user to control what retrieval metric they want to optimise for

Breaking change?

  • No
  • Yes — details below
If yes, fill this in

What breaks:

Before → after:

// before

// after

Migration:

How it was tested

Checklist

  • Tests pass locally
  • Added/updated tests for the change (or explained why not)
  • Docs updated if behavior changed

Notes for reviewers

@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86%. Comparing base (1eb5ebe) to head (a1d3580).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@         Coverage Diff         @@
##           main   #200   +/-   ##
===================================
  Coverage    85%    86%           
===================================
  Files        56     56           
  Lines      3459   3461    +2     
===================================
+ Hits       2974   2980    +6     
+ Misses      407    403    -4     
  Partials     78     78           
Flag Coverage Δ
go 86% <100%> (+<1%) ⬆️
python 85% <100%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
internal/graph/in_memory.go 86% <100%> (+<1%) ⬆️
internal/query/parser/ast.go 81% <100%> (+2%) ⬆️
...ython/src/fraise_sdk/integrations/claude_agents.py 100% <100%> (ø)
sdk/python/src/fraise_sdk/query.py 96% <100%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RonsenbergVI RonsenbergVI changed the title chore: add depth parameter feat: add depth parameter Aug 22, 2026
@RonsenbergVI
RonsenbergVI marked this pull request as ready for review August 22, 2026 08:41
@RonsenbergVI
RonsenbergVI merged commit 3dab727 into main Aug 22, 2026
44 of 47 checks passed
@RonsenbergVI
RonsenbergVI deleted the chore/add-depth-parameter branch August 22, 2026 08:44
RonsenbergVI added a commit that referenced this pull request Aug 22, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.0-beta.2](python/v0.1.0-beta.1...python/v0.1.0-beta.2)
(2026-08-22)


### Features

* add depth parameter
([#200](#200))
([3dab727](3dab727))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant