Skip to content

test(implicit_feedback): age-vs-alpha-drift Pearson correlation guard (#555) - #562

Closed
robotrocketscience wants to merge 1 commit into
mainfrom
test/issue-555-alpha-age-correlation
Closed

test(implicit_feedback): age-vs-alpha-drift Pearson correlation guard (#555)#562
robotrocketscience wants to merge 1 commit into
mainfrom
test/issue-555-alpha-age-correlation

Conversation

@robotrocketscience

@robotrocketscience robotrocketscience commented May 10, 2026

Copy link
Copy Markdown
Owner

Closes #555 — follow-up from #546 (which closed as duplicate of shipped #191).

What lands

New file: tests/test_implicit_feedback_age_correlation.py. Single test that:

  1. Builds a synthetic 1-week workload: 200 beliefs spread uniformly across the 7-day window. Per-belief retrieval count ~ Poisson(λ=2), with each retrieval placed at a uniform random time within the belief's lifetime — so retrieval frequency is uncorrelated with age by construction.
  2. ~15% of beliefs receive an explicit feedback event that cancels their implicit-sweep rows (per the grace-window logic).
  3. Drives the deferred sweeper end-to-end: T_sweep = T_end + 2·T_grace so every grace window has elapsed.
  4. Computes scipy.stats.pearsonr(age_days, alpha − alpha_initial).
  5. Asserts the sample r falls in the documented bound.
  6. Reproducible: all RNG seeded explicitly (default seed 42).

Measured value at seed 42: r = -0.035 (well within the bound).

Spec deviation — please review

Issue body specifies bound [0.0, 0.5]. This test ships [-0.2, 0.5].

Rationale: the issue body also specifies "retrieval frequency must be uncorrelated with age." With a truly decorrelated workload, the true correlation is 0 and the sample r at N=200 hovers around 0 with σ ≈ 0.07 (standard error of Pearson r at this sample size). Clamping the lower bound at exactly 0.0 would produce spurious failures on roughly half of seeds (any time noise pushes r slightly negative).

The lower bound -0.2 (about 3σ below zero) catches a real "systematic anti-correlation" regression — sweeper bias that disproportionately suppresses old beliefs — without firing on sampling noise. The upper bound 0.5 is preserved exactly as specified — that's the actual guard for the "implicit feedback becomes a clock" regression the issue is concerned about.

If the operator prefers the strict [0.0, 0.5] bound, the test should add multi-seed averaging (e.g. mean r across 30 seeds) so the noise floor doesn't trip the lower edge — that's a more involved change. Flag here so the reviewer can choose.

The test docstring includes the same explanation so a future maintainer can reason about the bound.

Out of scope

Per the issue body:

  • Tuning epsilon / T_grace (tuning concern, not regression guard).
  • Production telemetry (this is a synthetic-workload guard).

Notes

Summary by Sourcery

Tests:

  • Introduce a synthetic one-week workload test that asserts Pearson correlation between belief age and alpha drift stays within a safe range, ensuring the sweeper does not effectively act as a clock or penalise older beliefs.

…#555)

Synthetic 1-week workload: 200 beliefs created uniformly over 7 days,
retrieval counts drawn from Poisson(lam=2) and decorrelated from age by
construction. Sweeper driven end-to-end; asserts Pearson r(age, alpha_drift)
in [-0.2, 0.5] -- guards against the mechanism becoming a pure clock (r>0.5)
while tolerating sampling noise near zero (lower bound -0.2 ~= 3 sigma).
@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@robotrocketscience has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 minutes and 11 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 01607128-9f93-4651-8af3-df626141bd8e

📥 Commits

Reviewing files that changed from the base of the PR and between 4bb9ffe and 8292789.

📒 Files selected for processing (1)
  • tests/test_implicit_feedback_age_correlation.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/issue-555-alpha-age-correlation

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.

@sourcery-ai

sourcery-ai Bot commented May 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a new regression test that builds a synthetic 1-week implicit-feedback workload, runs the deferred-feedback sweeper end-to-end, and validates that the Pearson correlation between belief age and alpha drift stays within a statistically justified bound [-0.2, 0.5] to guard against the sweeper effectively becoming a time-based clock or penalizing older beliefs.

File-Level Changes

Change Details Files
Introduce a synthetic-workload regression test that checks Pearson correlation between belief age and alpha drift stays within [-0.2, 0.5].
  • Create a reproducible workload builder that seeds RNG, creates 200 beliefs uniformly over a 7-day window, and enqueues retrieval events whose counts are drawn from a capped Poisson distribution and placed uniformly within each belief’s lifetime to decorrelate retrieval frequency from age.
  • Inject explicit positive feedback events for a fixed fraction of beliefs inside the grace window so implicit-sweep rows are cancelled according to existing grace-window logic.
  • Run the deferred-feedback sweeper at a time chosen so all grace windows have elapsed, then compute ages and alpha drifts for all beliefs and assert the Pearson correlation lies between -0.2 and 0.5, emitting a descriptive failure message if bounds are violated.
  • Implement small helpers for formatting timestamps, Poisson sampling, computing belief age in days, and document in the test docstring the statistical rationale for using a lower bound of -0.2 instead of 0.0 and preserving the 0.5 upper bound.
tests/test_implicit_feedback_age_correlation.py

Assessment against linked issues

Issue Objective Addressed Explanation
#555 Add a regression guard that, on a synthetic 1-week workload, runs the deferred-feedback sweeper, computes Pearson correlation between belief age and (alpha − alpha_initial), and asserts that the correlation lies in the specified range [0.0, 0.5]. The PR adds a test that builds a 1-week synthetic workload, runs the sweeper end-to-end, computes Pearson r(age_days, alpha − alpha_initial), and asserts bounds on r. However, the assertion uses the range [-0.2, 0.5] instead of the issue’s specified [0.0, 0.5], explicitly called out in the PR as a spec deviation. Thus the test logic does not fully match the requested bound.
#555 Document the synthetic workload shape so that the correlation audit is reproducible.

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

@robotrocketscience robotrocketscience added author-Faraday PR coordination mutex attn:review Needs review (PR open, awaiting reviewer) labels May 10, 2026
@github-actions github-actions Bot added the attn:merge-conflict PR branch needs rebase label May 10, 2026
@github-actions

Copy link
Copy Markdown

This PR is now behind main. Rebase locally so your commit signatures stay intact:

git fetch origin && git checkout 'test/issue-555-alpha-age-correlation' && git rebase origin/main
# resolve conflicts if any, then
git push --force-with-lease

Auto-rebase was removed because the bot has no signing key; rebasing as the bot strips author signatures and the required_signatures rule on main then blocks the merge. See #341.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Maxwell:2026-05-10T05:21:54Z]

@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 left some high level feedback:

  • In _build_workload, the explicit-feedback loop repeatedly calls belief_ids.index(bid), which is O(N^2); consider building a dict mapping belief_id -> creation_offset_s once and reusing it to avoid the repeated list search.
  • You have the window length expressed as _WINDOW_SECONDS = WINDOW_DAYS * 86_400 and also hardcode 86_400.0 in _age_days; using a single shared constant for seconds-per-day would reduce the risk of these diverging in future changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_build_workload`, the explicit-feedback loop repeatedly calls `belief_ids.index(bid)`, which is O(N^2); consider building a `dict` mapping `belief_id -> creation_offset_s` once and reusing it to avoid the repeated list search.
- You have the window length expressed as `_WINDOW_SECONDS = WINDOW_DAYS * 86_400` and also hardcode `86_400.0` in `_age_days`; using a single shared constant for seconds-per-day would reduce the risk of these diverging in future changes.

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.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

Closing this PR per operator review. The substantive issue isn't the bound numbers — it's the choice of correlation measure.

Pearson r only detects linear correlation. A non-linear age dependence — e.g. a sweeper bug that disproportionately suppresses both very-young and very-old beliefs (U-shape), or a mid-window plateau — would produce r ≈ 0 and slip past this guard entirely. The "implicit feedback becomes a clock" failure mode the issue is trying to catch is not guaranteed to be linear in age, so a Pearson-only guard is the wrong tool for the job.

The test (and the issue body) need to switch to non-linear correlation measures:

  1. Chatterjee's ξ coefficient (Chatterjee 2021, A New Coefficient of Correlation, JASA). ξ ∈ [0, 1]: 0 iff Y is independent of X, 1 iff Y is a measurable function of X. Detects arbitrary functional dependence including non-monotonic. Available via the xicor Python package or implementable from scratch (~10 lines on ranks).
  2. One additional non-linear measure — likely distance correlation (Székely-Rizzo 2007) which is 0 iff independent and detects non-linear/non-monotonic dependence. The dcor package implements it. Spearman ρ alone isn't sufficient — it catches monotonic but not U-shaped dependence.

Issue #555 is being reopened with a revised acceptance bullet specifying the correlation measures. The bound numbers will follow from that.

Closing this PR rather than asking for changes because the rewrite is large enough that a fresh PR off updated spec is cleaner.

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Maxwell:2026-05-10T05:27:01Z]

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

Labels

attn:merge-conflict PR branch needs rebase attn:review Needs review (PR open, awaiting reviewer) author-Faraday PR coordination mutex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2.1] follow-up: belief-age vs alpha-drift correlation audit

1 participant