Skip to content

feat(retrieval): flip query_strategy default legacy-bm25 → stack-r1-r3 (#718) - #719

Merged
github-actions[bot] merged 4 commits into
mainfrom
feat/issue-718-stack-r1-r3-default
May 13, 2026
Merged

feat(retrieval): flip query_strategy default legacy-bm25 → stack-r1-r3 (#718)#719
github-actions[bot] merged 4 commits into
mainfrom
feat/issue-718-stack-r1-r3-default

Conversation

@robotrocketscience

@robotrocketscience robotrocketscience commented May 12, 2026

Copy link
Copy Markdown
Owner

Summary

PR-3 of the #291 sequencing: flip the canonical query_strategy default from legacy-bm25 to stack-r1-r3. Closes #718.

What changed

Canonical flip (one constant cascades everywhere):

  • src/aelfrice/query_understanding/strategy.py:41DEFAULT_STRATEGY = LEGACY_STRATEGYSTACK_R1_R3_STRATEGY. This is the single source-of-truth constant; it propagates through RebuilderConfig.query_strategy default (context_rebuilder.py:633), the malformed-config fallback at context_rebuilder.py:791,803, and the rebuild_v14 kwarg default (context_rebuilder.py:312, flipped from LEGACY_STRATEGY to DEFAULT_QUERY_STRATEGY).
  • src/aelfrice/hook.py:1694 — private helper kwarg default flipped in lockstep for internal consistency.

Docs (separate commit): query_understanding/{__init__,strategy}.py module docstrings and the context_rebuilder.py doc strings at 350-353 + 633-638 now lead with stack-r1-r3 and describe legacy-bm25 as the opt-in escape hatch until PR-4 removes it.

Tests updated (assertion flip only — these tests pin the documented default, not behaviour the bench gate covers):

  • test_transform_default_is_legacy_is_stack_r1_r3
  • test_config_default_query_strategy_is_legacy_is_stack_r1_r3
  • test_rebuild_default_query_strategy_is_legacy_is_stack_r1_r3
  • Two malformed-config fallback tests (test_config_invalid_query_strategy_falls_back_to_default, test_config_non_string_query_strategy_falls_back) — fallback now resolves to the new default (STACK_R1_R3_STRATEGY).

test_config_explicit_legacy_value_loads is unchanged — opt-in legacy-bm25 via TOML still loads as such.

Bench evidence justifying the flip

Labeled query-strategy corpus (30 rows, captured 2026-05-12 against the lab-side fixture; reproduce from any seat with the lab tree via AELFRICE_CORPUS_ROOT=$LAB/tests/corpus/v2_0 uv run pytest tests/bench_gate/test_query_strategy.py -v):

metric legacy-bm25 stack-r1-r3 delta
mean NDCG@k 0.3006 0.5858 +0.2851 absolute (+94.8%)
p99 latency 3.84 ms 4.50 ms +0.66 ms (13% of 5 ms budget)

Both bench gates (tests/bench_gate/test_query_strategy.py::test_query_strategy_uplift and …_latency) PASS on github/main HEAD.

Out of scope

  • Removing the legacy-bm25 code path — sequenced as PR-4, one minor release post-flip.
  • Multi-token / longer-window strategies beyond stack-r1-r3.

Milestone

The issue body raised "(a) v3.0 vs (b) v3.1" as open. Filing for v3.0 (option (a)) — bench evidence is in hand, v3.0 is the natural cut. If the operator prefers (b), holding this PR until v3.1 is a one-line milestone re-tag.

Closes #718.

Summary by Sourcery

Flip the canonical query_strategy default from legacy-bm25 to stack-r1-r3 across the query understanding pipeline and rebuilder configuration.

Enhancements:

  • Update query strategy dispatcher to make stack-r1-r3 the default strategy while keeping legacy-bm25 as an explicit opt-in escape hatch.
  • Adjust RebuilderConfig and rebuild_v14 defaults and docstrings to align with the new stack-r1-r3 default and document the deprecation path for legacy-bm25.

Documentation:

  • Document the new stack-r1-r3 default, associated bench results, and planned removal of legacy-bm25 in module docstrings and the changelog.

Tests:

  • Update query strategy tests to assert stack-r1-r3 as the default and ensure config fallbacks and rebuild_v14 behavior are consistent with the new default.

Summary by CodeRabbit

  • Changes

    • Default query processing strategy switched to a stack-based "stack-r1-r3" approach for improved entity expansion and IDF clipping; legacy strategy remains opt-in.
  • Documentation

    • Docs updated to describe the new default, rollout timeline, and legacy escape hatch.
  • Tests

    • Test suite updated and renamed to verify the new default behavior and config fallbacks.

Review Change Stack

@sourcery-ai

sourcery-ai Bot commented May 12, 2026

Copy link
Copy Markdown

Reviewer's Guide

Flips the canonical query_strategy default from legacy-bm25 to stack-r1-r3 by updating the central DEFAULT_STRATEGY constant and its downstream consumers, aligning docs and tests, and keeping legacy-bm25 as an explicit opt-in escape hatch.

Flow diagram for query_strategy default resolution after flip

flowchart TD
    DEFAULT_STRATEGY[DEFAULT_STRATEGY = STACK_R1_R3_STRATEGY]

    DEFAULT_STRATEGY --> RebuilderConfig_query_strategy[RebuilderConfig.query_strategy default]
    DEFAULT_STRATEGY --> rebuild_v14_query_strategy[rebuild_v14 query_strategy kwarg default]
    DEFAULT_STRATEGY --> malformed_fallback[malformed config fallback query_strategy]
    DEFAULT_STRATEGY --> hook_rebuild_and_format_query_strategy[_rebuild_and_format query_strategy default]

    RebuilderConfig_query_strategy --> transform_query_call["transform_query(raw_query, store, query_strategy)"]
    rebuild_v14_query_strategy --> transform_query_call
    malformed_fallback --> transform_query_call
    hook_rebuild_and_format_query_strategy --> rebuild_v14_query_strategy
Loading

File-Level Changes

Change Details Files
Flip canonical query_strategy default to stack-r1-r3 and propagate through configuration and rebuild plumbing.
  • Set DEFAULT_STRATEGY to STACK_R1_R3_STRATEGY in the query-understanding strategy dispatcher.
  • Use DEFAULT_QUERY_STRATEGY as the default query_strategy parameter in rebuild_v14 instead of LEGACY_STRATEGY.
  • Keep RebuilderConfig.query_strategy defaulted to DEFAULT_QUERY_STRATEGY and rely on it for malformed-config fallbacks.
  • Align the private _rebuild_and_format helper’s query_strategy default with the new stack-r1-r3 default.
src/aelfrice/query_understanding/strategy.py
src/aelfrice/context_rebuilder.py
src/aelfrice/hook.py
Update documentation to describe stack-r1-r3 as the default and legacy-bm25 as an opt-in escape hatch pending removal. src/aelfrice/query_understanding/__init__.py
src/aelfrice/query_understanding/strategy.py
src/aelfrice/context_rebuilder.py
CHANGELOG.md
Adjust tests to pin the new default stack-r1-r3 behavior and configuration fallbacks while preserving explicit legacy-bm25 opt-in coverage.
  • Rename and update tests that asserted legacy-bm25 as the default so they assert stack-r1-r3 instead for the transformer, config, and rebuild_v14.
  • Change malformed-config fallback tests to expect STACK_R1_R3_STRATEGY as the resolved query_strategy.
  • Update the rebuild_v14 default-behavior test to compare the implicit default against an explicit STACK_R1_R3_STRATEGY call instead of LEGACY_STRATEGY.
  • Keep the explicit legacy-bm25 load test unchanged to ensure opt-in behavior remains supported.
tests/test_query_strategy.py

Assessment against linked issues

Issue Objective Addressed Explanation
#718 Change the canonical default query_strategy from "legacy-bm25" to "stack-r1-r3" throughout the codebase (dispatcher DEFAULT_STRATEGY, RebuilderConfig default and malformed-config fallback, rebuild_v14 kwarg default, and hook helper defaults), while keeping legacy-bm25 available via explicit configuration.
#718 Update all relevant documentation and inline comments (context_rebuilder docstrings, query_understanding module/strategy docs, CONFIG.md, and CHANGELOG) to state that stack-r1-r3 is the default, describe legacy-bm25 as an opt-in escape hatch until its planned removal, and reference this flip as PR-3 in the #291 sequencing. The PR updates docstrings in context_rebuilder.py and the query_understanding package, and adds a detailed Unreleased CHANGELOG entry for the default flip, but it does not modify docs/CONFIG.md as explicitly called out in the issue scope (docs/CONFIG.md:19,23,37,76) and acceptance criteria. Therefore the documentation update is only partially completed.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8ad68ddf-c0a8-4f63-9aa7-f692fb24017e

📥 Commits

Reviewing files that changed from the base of the PR and between e8842f5 and 0a0443b.

📒 Files selected for processing (1)
  • src/aelfrice/hook.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/aelfrice/hook.py

📝 Walkthrough

Walkthrough

This PR flips the default query rewriting strategy from legacy-bm25 (passthrough) to stack-r1-r3 (entity expansion + per-store IDF clipping) across the rebuilder API and hook, updates dispatcher/docstrings, and adjusts tests to assert the new default; legacy-bm25 remains an explicit opt-in.

Changes

Query Strategy Default Flip

Layer / File(s) Summary
Core constant and rebuild API defaults
src/aelfrice/query_understanding/strategy.py, src/aelfrice/context_rebuilder.py, src/aelfrice/hook.py
The exported DEFAULT_STRATEGY constant flips from LEGACY_STRATEGY to STACK_R1_R3_STRATEGY. rebuild_v14 and _rebuild_and_format update their query_strategy parameter defaults and docstrings to reflect stack-r1-r3 as the default; imports/signature updated to use the shared default.
Query understanding dispatcher documentation
src/aelfrice/query_understanding/__init__.py
Module docstring reworded to state that stack-r1-r3 is the default dispatcher choice, legacy-bm25 is opt-in, and per-store BM25/quantile data is sourced via store_cache.get_bm25_and_quantiles.
Test assertions and default coverage
tests/test_query_strategy.py
Test names and assertions updated to verify that transform_query, RebuilderConfig, load_rebuilder_config fallbacks, and rebuild_v14 now default to stack-r1-r3 and that invalid/non-string inputs fall back to the new default.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #291: Parent umbrella issue (rebuild redesign / query understanding stack) defining the PR-3 rollout milestone for flipping the default query strategy after bench-gate validation.
  • #720: Docs/CONFIG.md updates for the rebuilder default; related to flipping config documentation to the new default.

Possibly related PRs

Suggested labels

attn:review

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: flipping the query_strategy default from legacy-bm25 to stack-r1-r3, which is the primary focus of the entire PR.
Description check ✅ Passed The PR description comprehensively covers the summary, what changed, bench evidence, test updates, and out-of-scope items. It aligns well with the template requirements despite the template structure not being explicitly followed in sections.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #718: flipping DEFAULT_STRATEGY constant, updating rebuild_v14 and hook.py defaults, updating docstrings, and verifying with bench evidence showing 94.8% NDCG improvement within latency budget.
Out of Scope Changes check ✅ Passed All changes are directly aligned with PR objective #718 requirements: constant flip, function defaults, docstrings, and test updates for the new default. No unrelated changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-718-stack-r1-r3-default

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@robotrocketscience robotrocketscience added the attn:review Needs review (PR open, awaiting reviewer) label May 12, 2026
@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown

PR-size soft cap

This PR is over the advisory size threshold:

  • 75 changed lines (limit: 200)
  • 6 changed files (limit: 3)

Bigger PRs collide with more open work, which under the parallel-session workflow tends to produce repeated attn:merge-conflict cycles (see #602). When practical, split into smaller PRs that each touch a focused surface.

This is advisory only — nothing is blocked. If the size is intentional (large refactor, module removal, generated code), apply the size:override label and this comment will be removed on the next push.

@robotrocketscience robotrocketscience added the author-Schwarzchild Authored by parallel session Schwarzchild label May 12, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In _rebuild_and_format the query_strategy default is still a bare string literal; consider wiring this through DEFAULT_STRATEGY (or a shared constant) to keep it in lockstep with the canonical default and avoid future drift.
  • The new docstrings/CHANGELOG entries embed detailed bench metrics and internal issue sequencing; you might want to trim or generalize some of this (e.g., exact NDCG deltas, “phase-1b operator-week”) to keep the public surface focused on behavior rather than time-bound process details.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_rebuild_and_format` the `query_strategy` default is still a bare string literal; consider wiring this through `DEFAULT_STRATEGY` (or a shared constant) to keep it in lockstep with the canonical default and avoid future drift.
- The new docstrings/CHANGELOG entries embed detailed bench metrics and internal issue sequencing; you might want to trim or generalize some of this (e.g., exact NDCG deltas, “phase-1b operator-week”) to keep the public surface focused on behavior rather than time-bound process details.

## Individual Comments

### Comment 1
<location path="src/aelfrice/hook.py" line_range="1694" />
<code_context>
     floor_session: float = 0.0,
     floor_l1: float = 0.0,
-    query_strategy: str = "legacy-bm25",
+    query_strategy: str = "stack-r1-r3",
 ) -> str:
     """Open the store and run the v1.4 rebuild.
</code_context>
<issue_to_address>
**suggestion:** Use the shared default strategy constant instead of a hard-coded string literal.

This default is hard-coded, while other callers (e.g., `rebuild_v14`) use `DEFAULT_QUERY_STRATEGY`. If the default strategy changes, this literal may get out of sync. Please use the shared constant (or a single source of truth) so the default only needs to be updated in one place.

Suggested implementation:

```python
    floor_session: float = 0.0,
    floor_l1: float = 0.0,
    query_strategy: str = DEFAULT_QUERY_STRATEGY,
) -> str:

```

If `DEFAULT_QUERY_STRATEGY` is not already imported or defined in this module, you will need to:
1. Import it from the appropriate module (e.g., `from aelfrice.constants import DEFAULT_QUERY_STRATEGY`) or
2. Ensure it is defined earlier in `src/aelfrice/hook.py`.

Match whatever import/definition pattern is used elsewhere in the codebase where `DEFAULT_QUERY_STRATEGY` is referenced (e.g., in `rebuild_v14`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/aelfrice/hook.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/aelfrice/hook.py`:
- Line 1694: The parameter default for query_strategy is hardcoded to
"stack-r1-r3" which duplicates the canonical default; change the default to use
the shared constant DEFAULT_STRATEGY instead (e.g., replace the literal default
for query_strategy with DEFAULT_STRATEGY or make query_strategy optional and
assign DEFAULT_STRATEGY inside the function), ensuring you reference the
existing DEFAULT_STRATEGY symbol rather than repeating the string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 927d1235-da47-4221-b55e-741381fc9b08

📥 Commits

Reviewing files that changed from the base of the PR and between 1098c33 and 4f4d445.

⛔ Files ignored due to path filters (1)
  • CHANGELOG.md is excluded by !**/CHANGELOG.md
📒 Files selected for processing (5)
  • src/aelfrice/context_rebuilder.py
  • src/aelfrice/hook.py
  • src/aelfrice/query_understanding/__init__.py
  • src/aelfrice/query_understanding/strategy.py
  • tests/test_query_strategy.py

Comment thread src/aelfrice/hook.py Outdated
@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Curie:2026-05-12T19:21:18Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:newton:2026-05-12T19:22:20Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:noether:2026-05-12T19:22:23Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:newton:2026-05-12T19:22:25Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:noether:2026-05-12T19:22:28Z]

@robotrocketscience robotrocketscience left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

LGTM. Approving for merge.

Diff matches #718 spec. Three atomic SSH-signed commits flip DEFAULT_STRATEGYSTACK_R1_R3_STRATEGY at every cascade point the issue named:

  • query_understanding/strategy.py:42 — module constant
  • context_rebuilder.py:312rebuild_v14 kwarg default
  • context_rebuilder.py:632RebuilderConfig.query_strategy default (also covers the malformed-config fallback path, exercised by test_config_invalid_query_strategy_falls_back_to_default / ..._non_string_...)
  • hook.py:1694_rebuild_and_format kwarg default

VALID_STRATEGIES still contains both, so explicit query_strategy="legacy-bm25" keeps working until PR-4. Doc strings on rebuild_v14, RebuilderConfig, and query_understanding/__init__.py all reflect the new default + PR-3/PR-4 sequencing. CHANGELOG entry under ## [3.0.0] - Unreleased is precise about the bench evidence and the kept opt-in.

Tests updated correctly. Six default-value assertions in tests/test_query_strategy.py flipped; test_rebuild_default_query_strategy_is_stack_r1_r3 now pins byte-identity of the no-arg call against the new default, which is the right invariant.

Discretion grep on the diff: clean.

Acceptance gap (non-blocking, follow-up issue worth filing): docs/CONFIG.md is not touched in this PR, but the #718 acceptance lists it. The reason is the doc never had a [rebuilder] section to begin with — grep -n 'query_strategy\|rebuilder' docs/CONFIG.md is empty on main. So there's nothing to flip from legacy-bm25stack-r1-r3 in CONFIG.md; the gap is "this knob was never documented in user-facing config docs." That's a pre-existing doc hole, not a regression from this PR. Suggest opening a small follow-up to add a [rebuilder] query_strategy entry to docs/CONFIG.md so power users have a discoverable knob, but it shouldn't block this merge.

CI: pytest 3.12 + 3.13 green, CodeQL clean, staging-gate green, all 3 commits SSH-signed (%G? = G). FF on github/main.

Adding ready-to-merge to ride the merge-train.

@robotrocketscience robotrocketscience added ready-to-merge Trigger merge-train: FF main to this PR's head and removed attn:review Needs review (PR open, awaiting reviewer) labels May 12, 2026
@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Curie:2026-05-12T19:23:22Z]

@github-actions

Copy link
Copy Markdown

merge-train: blocked

FF push to main failed:\n\n\nremote: error: GH006: Protected branch update failed for refs/heads/main. remote: remote: - All comments must be resolved. To https://github.com/robotrocketscience/aelfrice ! [remote rejected] 4f4d445666db7796b703136c1026fc9df771ef45 -> main (protected branch hook declined) error: failed to push some refs to 'https://github.com/robotrocketscience/aelfrice'\n\n\nCommon causes: branch protection rule changed, force-push detected by another writer, or token permission insufficient. Re-add the label after investigating.

The ready-to-merge label has been removed. Address the issue above and re-add the label when you're ready for another attempt.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Newton:2026-05-12T19:56:12Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

Review — PR #719 (Newton)

Verification

  • uv run pytest tests/test_query_strategy.py tests/test_context_rebuilder.py tests/bench_gate/: 65 passed, 27 skipped (skips are bench-gate runs needing the lab corpus root).
  • Full local suite: 3755 passed, 59 skipped, 75 xfailed in 105s. No regression.
  • CI checks: all required green (pytest 3.12 / 3.13, CodeQL python+actions, Staging Gate secrets-scan / pattern-scan / history-scan / commit-msg-prefix / pr-title-prefix / pr-body-issue-link / release-docs-check, deptry, vulture, size-check, typos, Sourcery, CodeRabbit). mergeable: MERGEABLE.

Diff shape

40 add / 34 del across 6 files. The flip is consistently propagated through every default-bearing surface:

Surface Change
query_understanding/strategy.py:42 DEFAULT_STRATEGY = LEGACY_STRATEGYSTACK_R1_R3_STRATEGY
context_rebuilder.py:312 rebuild_v14(..., query_strategy=LEGACY_STRATEGY)DEFAULT_QUERY_STRATEGY
context_rebuilder.py:RebuilderConfig.query_strategy docstring flipped (field already used DEFAULT_QUERY_STRATEGY, so it inherits the flip)
hook.py:1694 _rebuild_and_format(..., query_strategy="legacy-bm25")"stack-r1-r3" (hardcoded literal — see nit below)
tests/test_query_strategy.py 5 assertions updated (default constant, RebuilderConfig default, malformed-config fallback, non-string fallback, rebuild_v14 plumbing equivalence)
CHANGELOG.md unreleased entry under ### Changed with bench numbers + threshold framing

The legacy-bm25 escape hatch stays callable (kwarg + TOML override), and the docstrings everywhere now read "default since v3.0 / #291 PR-3 / #718" with PR-4 sequenced as the removal step.

Acceptance checklist vs issue body

Nit (non-blocking): hardcoded literal at hook.py:1694

_rebuild_and_format uses the string literal "stack-r1-r3" rather than importing DEFAULT_QUERY_STRATEGY (or STACK_R1_R3_STRATEGY) from query_understanding.strategy. Future flips would then need to touch two places. Faithful to the issue body's "three lines" scope, but if hook.py grows another flip cycle, hoisting to the constant would shrink the diff. Not blocking — pre-existing pattern.

Discretion / staging-gate

CI staging-gate scans (secrets, pattern, history, commit-msg-prefix, pr-title-prefix, pr-body-issue-link, release-docs-check) all PASS. No bench artifact files in the diff (corpus stays out of the repo per project policy).

Verdict

LGTM. Ship as part of the v3.0 cron, paired with PR #722 for the docs companion. Can't formally approve (gh auth = PR author from your seat); leaving as a comment review.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Newton:2026-05-12T19:59:29Z]

#718)

PR-3 of the #291 sequencing. Flips the canonical DEFAULT_STRATEGY
constant in query_understanding.strategy, which cascades through
RebuilderConfig.query_strategy (default + malformed-config fallback)
and rebuild_v14's kwarg default. Hook helper kwarg default flipped
in lockstep.

Bench evidence (#718 body, 2026-05-12 against lab v0_1 corpus,
30 labeled rows): mean NDCG@k 0.3006 → 0.5858 (+94.8%); p99
latency 3.84 ms → 4.50 ms (+0.66 ms, 13% of the 5 ms budget).
Both bench-gate tests (test_query_strategy_uplift and
test_query_strategy_latency) PASS on github/main.

Tests updated to assert the new default (assertion-only; no
behavior tested by the flip itself — that's the bench gate's job).
#718)

Module/class docstrings now lead with stack-r1-r3 (default since
#291 PR-3 / #718) and describe legacy-bm25 as the opt-in escape
hatch retained until PR-4 removes it. Mirrors the actual default
constant flipped in the preceding commit.
@robotrocketscience
robotrocketscience force-pushed the feat/issue-718-stack-r1-r3-default branch from 4f4d445 to e8842f5 Compare May 13, 2026 02:52
@robotrocketscience

Copy link
Copy Markdown
Owner Author

Rebased onto current main (4f4d445e8842f5). Three commits replayed cleanly; CHANGELOG.md inserts at separate offsets so no merge conflict. All commits re-signed (G). Discretion grep clean. Local tests: test_query_strategy.py + test_query_understanding.py + test_context_rebuilder.py 65/65 in 6.7s.

Out of replay-soak-gate path scope (touches context_rebuilder.py, hook.py, query_understanding/* — none of derivation.py, replay.py, ingest.py, scanner.py), so this PR doesn't see the consecutive-green soak check.

Existing prior-session LGTM stands. Adding ready-to-merge.

@robotrocketscience robotrocketscience added ready-to-merge Trigger merge-train: FF main to this PR's head and removed attn:merge-conflict PR branch needs rebase labels May 13, 2026
@github-actions

Copy link
Copy Markdown

merge-train: blocked

1 review thread(s) are unresolved on these files: src/aelfrice/hook.py. Resolve them on the PR (click 'Resolve conversation' on each) and re-add the label.

The ready-to-merge label has been removed. Address the issue above and re-add the label when you're ready for another attempt.

@github-actions github-actions Bot removed the ready-to-merge Trigger merge-train: FF main to this PR's head label May 13, 2026
…718)

Replaces the hardcoded "stack-r1-r3" literal default with the
canonical DEFAULT_STRATEGY constant from query_understanding.strategy,
matching the pattern already in context_rebuilder.py. Removes a
drift surface: future strategy renames or default changes now flow
through one constant.
@robotrocketscience

Copy link
Copy Markdown
Owner Author

Addressed the sourcery + coderabbit conversation threads with commit 0a0443b: hook.py _rebuild_and_format now uses DEFAULT_STRATEGY from aelfrice.query_understanding instead of the hardcoded "stack-r1-r3" literal. Matches the pattern already in context_rebuilder.py.

Both threads resolved. Re-adding ready-to-merge.

Tests: 104/104 across test_query_strategy.py + test_hook_user_prompt_submit.py + test_hook_import_resilience.py + test_context_rebuilder_hook.py in 9s.

@robotrocketscience robotrocketscience added the ready-to-merge Trigger merge-train: FF main to this PR's head label May 13, 2026
@github-actions

Copy link
Copy Markdown

merge-train: merged 0a0443bmain via FF push.

@github-actions github-actions Bot removed the ready-to-merge Trigger merge-train: FF main to this PR's head label May 13, 2026
@github-actions
github-actions Bot merged commit 0a0443b into main May 13, 2026
33 checks passed
@robotrocketscience
robotrocketscience deleted the feat/issue-718-stack-r1-r3-default branch May 14, 2026 04:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author-Schwarzchild Authored by parallel session Schwarzchild

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(retrieval): flip query_strategy default legacy-bm25 → stack-r1-r3 (#291 PR-3)

1 participant