Skip to content

refactor(bot): break Cycle C via direct imports + extract audioFeatures/vcWeights (#889) - #931

Merged
LucasSantana-Dev merged 2 commits into
release/v2.14.0from
refactor/cycle-c-889
May 22, 2026
Merged

LucasSantana-Dev merged 2 commits into
release/v2.14.0from
refactor/cycle-c-889

Conversation

@LucasSantana-Dev

Copy link
Copy Markdown
Owner

Resolves #889 — last runtime circular dependency in `packages/bot/src`.

What changed

Cycle C was `queueManipulation.ts ↔ autoplay/replenisher.ts` via a 6-symbol barrel import. 4 of those symbols already lived in standalone files (`candidateFallback.ts`); the other 2 needed minimal extraction:

  • `getTrackAudioFeatures` + `audioFeatureCache` → `autoplay/audioFeatures.ts`
  • `buildVcContributionWeights` → `autoplay/vcWeights.ts`

`replenisher.ts` now imports each symbol directly from its source. `queueManipulation.ts` and `queueRescue.ts` retain their public surface via re-export, so no consumer touches.

Madge

Unblocks promotion of `.github/workflows/madge.yml` from `continue-on-error: true` to a hard gate (separate follow-up PR).

Tests

  • 433/433 autoplay + queue + replenisher tests pass
  • 3075/3075 total bot suite pass (2 unrelated `prom-client` env failures in worktree only)

Closure-capture avoidance

The prior agent attempt at Cycle C broke 107 tests due to closure-captured state. This change keeps `audioFeatureCache` as a module-level `const LRUCache` — purely lexical relocation, no shape change.

ADR

`docs/decisions/2026-05-21-cycle-c-direct-imports-and-audio-features-extraction.md` records the decision, alternatives (B: larger extraction; C: accept the cycle; D: callback indirection), and revisit triggers.

Changelog

[Unreleased] Changed: break the last runtime circular dependency in `packages/bot/src` (Cycle C, #889).

…es/vcWeights

Resolves #889 — last runtime circular dep in packages/bot/src.

The cycle was queueManipulation.ts <-> autoplay/replenisher.ts via a
6-symbol barrel import. 4 of those symbols already lived in standalone
files (candidateFallback.ts); the other 2 needed minimal extraction:

  - getTrackAudioFeatures + audioFeatureCache (LRUCache) -> autoplay/audioFeatures.ts
  - buildVcContributionWeights -> autoplay/vcWeights.ts

replenisher.ts now imports each symbol directly from its source file.
queueManipulation.ts and queueRescue.ts keep their public surface via
re-export, so no consumer change.

Madge runtime cycles: 2 -> 1 (deferred type-only types/CustomClient
cycle remains, as documented in #871).

Tests: 433/433 autoplay+queue+replenisher pass. 3075/3075 total bot
suite pass (2 unrelated prom-client env failures in worktree only).

The closure-capture failure mode from the prior agent attempt is
avoided by keeping audioFeatureCache as a module-level const in its
new file -- purely lexical relocation, no shape change.

ADR: docs/decisions/2026-05-21-cycle-c-direct-imports-and-audio-features-extraction.md
@vercel

vercel Bot commented May 22, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment May 22, 2026 12:22am

Request Review

@greptile-apps greptile-apps 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai

coderabbitai Bot commented May 22, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@LucasSantana-Dev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 44 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: d624e66d-c2a6-49dd-9d6e-27f40052e19a

📥 Commits

Reviewing files that changed from the base of the PR and between 4d345e9 and 05e4785.

⛔ Files ignored due to path filters (1)
  • CHANGELOG.md is excluded by !**/CHANGELOG.md
📒 Files selected for processing (6)
  • docs/decisions/2026-05-21-cycle-c-direct-imports-and-audio-features-extraction.md
  • packages/bot/src/utils/music/autoplay/audioFeatures.ts
  • packages/bot/src/utils/music/autoplay/replenisher.ts
  • packages/bot/src/utils/music/autoplay/vcWeights.ts
  • packages/bot/src/utils/music/queueManipulation.ts
  • packages/bot/src/utils/music/queueRescue.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/cycle-c-889

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.

@greptile-apps greptile-apps 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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 1188ad4 into release/v2.14.0 May 22, 2026
27 of 28 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the refactor/cycle-c-889 branch May 22, 2026 00:27
LucasSantana-Dev added a commit that referenced this pull request May 22, 2026
…es/vcWeights (#889) (#931)

Resolves #889 — last runtime circular dependency in
\`packages/bot/src\`.

## What changed

Cycle C was \`queueManipulation.ts ↔ autoplay/replenisher.ts\` via a
6-symbol barrel import. 4 of those symbols already lived in standalone
files (\`candidateFallback.ts\`); the other 2 needed minimal extraction:

- \`getTrackAudioFeatures\` + \`audioFeatureCache\` →
\`autoplay/audioFeatures.ts\`
- \`buildVcContributionWeights\` → \`autoplay/vcWeights.ts\`

\`replenisher.ts\` now imports each symbol directly from its source.
\`queueManipulation.ts\` and \`queueRescue.ts\` retain their public
surface via re-export, so no consumer touches.

## Madge

- Before: 2 cycles (Cycle C + deferred type-only \`types/CustomClient\`
cycle)
- After: 1 cycle (only the deferred type-only one remains, as documented
in #871)

Unblocks promotion of \`.github/workflows/madge.yml\` from
\`continue-on-error: true\` to a hard gate (separate follow-up PR).

## Tests

- 433/433 autoplay + queue + replenisher tests pass
- 3075/3075 total bot suite pass (2 unrelated \`prom-client\` env
failures in worktree only)

## Closure-capture avoidance

The prior agent attempt at Cycle C broke 107 tests due to
closure-captured state. This change keeps \`audioFeatureCache\` as a
module-level \`const LRUCache\` — purely lexical relocation, no shape
change.

## ADR


\`docs/decisions/2026-05-21-cycle-c-direct-imports-and-audio-features-extraction.md\`
records the decision, alternatives (B: larger extraction; C: accept the
cycle; D: callback indirection), and revisit triggers.

## Changelog

[Unreleased] Changed: break the last runtime circular dependency in
\`packages/bot/src\` (Cycle C, #889).
LucasSantana-Dev added a commit that referenced this pull request May 22, 2026
10 PRs accumulated since v2.13.0 (cut 2026-05-21, shipped same-day).

## Added
- feat(bot): autoplay closed-loop telemetry writers (Phase B) #933
- feat(backend): /recommendations/history read path (Phase C) #935
- feat(download): cover + re-enable /download command #930
- feat(music): cover + re-enable collaborative playlist #929
- feat(management): /customcommand coverage #928
- feat(management): cover + re-enable /embed builder #927
- test(bot/recommendation): cover 4 untested handlers #926

## Changed
- refactor(bot): Cycle C closure of #889 — runtime cycles 2 to 1 #931
- refactor(bot/autoplay): Cycles A + B residuals — 4 to 2 #925
- chore(prisma): Recommendation model repurposed for telemetry #932

Roadmap status: Phase A+B+C of the autoplay recommendation roadmap
shipped in this release. Phase D (session-coherence layer) gated on
7 days of production baseline -- revisit 2026-05-29.

Also bundled via release-branch-autosync: fix(ci): v-prefix
trivy-action tag (#934) -- unblocks production Docker image
republishing.
LucasSantana-Dev added a commit that referenced this pull request May 22, 2026
v2.14.0 — 10 PRs since v2.13.0 (cut 2026-05-21).

## Highlights

**Autoplay recommendation telemetry (3-phase roadmap, ADR
\`2026-05-21-autoplay-recommendation-roadmap\`):**
- Phase A (#932) — Prisma \`Recommendation\` model repurposed for
closed-loop autoplay telemetry. New \`RecommendationSource\` enum,
\`signals: Jsonb\`, \`discordUserId\`, aggregation index.
- Phase B (#933) — non-throwing writers. Every autoplay pick writes a
row; \`playerFinish\` and \`playerSkip\` flip the outcome flags using
30% / 5s thresholds (exported constants for tuning).
- Phase C (#935) — read path. \`GET
/api/guilds/:guildId/recommendations/history?days=<n>\` returns
per-source acceptance rate + global summary aggregated over the window
(default 7d, clamped [1, 30]).
- **Phase D deferred.** Gated on 7 days of production baseline starting
after this release deploys. If per-source acceptance \u2265 85%, Phase D
becomes optional. Revisit 2026-05-29.

**bot/autoplay circular-dependency closure (#889 done):**
- #925 — Cycles A+B (queueMarkers, candidateContracts) — madge 4 → 2.
- #931 — Cycle C (audioFeatures, vcWeights) — madge 2 → 1 (only the
deferred type-only \`types/CustomClient\` cycle remains). Unblocks
promoting \`madge.yml\` to a blocking CI gate.

**Feature toggle re-enables (each with full test coverage):**
- \`/download\` (#930), collaborative playlist (#929), \`/embed\`
builder (#927).
- Test-only coverage adds: \`/customcommand\` (#928), 4 recommendation
handlers (#926).

**Bundled via release-branch-autosync:** \`fix(ci): v-prefix
trivy-action tag\` (#934) — unblocks production Docker image
republishing on main.

## Verification

- All 10 PRs passed CI (Quality Gates, SonarCloud, CodeQL, semgrep,
knip, lint, madge, security) before merging to release/v2.14.0.
- Bot suite: 3109+ tests passing across the autoplay + queue +
replenisher + recommendation + trackHandlers surface.
- Backend suite: 343+ integration tests passing including the new
\`/recommendations/history\` route.
- Shared suite: 12 new tests on \`recommendationTelemetryReadService\`.

## Deploy checklist

After merge:
1. Tag \`v2.14.0\` on the merge commit.
2. Verify the Docker publish workflow succeeds on the merge commit (was
the original failure mode pre-#934; now fixed).
3. Confirm homelab pulls the new images.
4. Begin 7-day baseline collection for the autoplay recommendation
telemetry.

## Migrations

One Prisma migration in this release:
\`20260521000000_recommendation_telemetry_phase_a\`. Repurposes the
unused \`recommendations\` table:
- Drops \`algorithm: String\` (was scaffolded, never written by any
service).
- Adds \`recommendationSource\` enum + \`signals\` Jsonb +
\`discordUserId\` + indexed by \`(guildId, source, createdAt)\`.
- \`confidence\` made nullable.

Safe to deploy: no production rows exist in the table prior to this
release.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added recommendation history endpoint to retrieve past recommendations
and acceptance rates by source
* Telemetry recording now tracks recommendation outcomes
(accepted/rejected) based on listening behavior
* New feature toggles for Embed Builder and Collaborative Playlist
support

* **Chores**
  * Bumped all package versions to 2.14.0
* Updated database schema to support recommendation source tracking and
telemetry

* **Tests**
* Added comprehensive test coverage for download and autoplay features,
collaborative playlist, and recommendation handlers

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/LucasSantana-Dev/Lucky/pull/936?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

This branch was successfully deployed

1 active deployment
Preview — 05e47852 Deployed May 22, 2026 by vercel[bot]
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