test: mutation-hardening — kill surviving mutants in pipeline/youtube/http/tenancy/crypto/cron - #89
Conversation
… hold status, inactive channel, DRY_RUN validation, decide-failure, cursor persistence)
…try/abort, keyword case-insensitivity
…oping, renewal cookie, NaN expiry, personal-org idempotency
…failure-reporting, OAuth cookie Secure, consent sweep bounds
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
✅ Deploy Preview for moderaty ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Review limit reached
Next review available in: 20 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
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. Comment |
🏁 CodeAnt Quality Gate ResultsCommit: ✅ Overall Status: PASSEDQuality Gate Details
|
Sequence DiagramThis PR hardens the scheduled moderation path by selecting eligible channels safely, applying rule decisions, enforcing the corresponding YouTube action, and persisting progress only after successful processing. sequenceDiagram
participant Scheduler
participant Database
participant Pipeline
participant YouTube
Scheduler->>Database: Select and claim eligible channel
Database-->>Scheduler: Least recently run active channel
Scheduler->>Pipeline: Run channel
Pipeline->>YouTube: Fetch new comments in time order
YouTube-->>Pipeline: Return new comments
Pipeline->>Pipeline: Apply moderation rules
Pipeline->>YouTube: Enforce delete ban or hold
Pipeline->>Database: Save actions and cursor
Scheduler->>Database: Record run and clear lease
Generated by CodeAnt AI |
There was a problem hiding this comment.
This PR adds 38 mutation-hardening tests targeting critical security and correctness paths. The test additions strengthen coverage in areas where mutants previously survived, particularly for:
- Cross-tenant isolation (session renewal/org repair scoped to caller only)
- Cryptographic nonce reuse prevention
- YouTube API parameter preservation (banAuthor, order, method)
- Cron channel selection and lease management
- Personal org race condition handling
All tests pass and build succeeds. Test-only changes with no production code modifications. Ready to merge.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
Not up to standards ⛔🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | ✅ 57 (≤ 100 complexity) |
| Duplication |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
PR Summary by QodoTest: mutation-hardening for pipeline enforcement, tenancy/session safety, crypto, and cron
AI Description
Diagram
High-Level Assessment
Files changed (11)
|
PR Code Suggestions ✨Previous suggestions up to commit
|
| Category | Suggestion | Severity | Generated at (UTC) |
| Api mismatch |
The renewal-cookie test cannot detect loss of the Secure attribute in productionThe test mocks src/hooks.server.test.ts [93-99] Why it matters? 🤔
(Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/hooks.server.test.ts
**Line:** 93:99
**Comment:**
*Api Mismatch: The test mocks `cookieSecure` to always return `false`, so it cannot verify that renewed session cookies use the production APP_URL-derived security setting. A regression that stops calling `cookieSecure` or hard-codes `secure: false` would still pass. Configure the mocked helper to return `true`, or mock the environment and assert the real helper is used for HTTPS.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix | Major | 2026-08-05 13:03
|
| Race condition |
Sequential calls do not verify safety against concurrent personal-organization creationThe two calls are sequential, so this only verifies ordinary idempotency and never src/lib/server/org.test.ts [320-321] Why it matters? 🤔
(Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/lib/server/org.test.ts
**Line:** 320:321
**Comment:**
*Race Condition: The two calls are sequential, so this only verifies ordinary idempotency and never exercises the check-then-insert race described by the test. Concurrent signups can still both observe no organization and cause a unique-constraint failure or duplicate creation. Run genuinely overlapping calls or simulate the insert conflict so the claimed raced-signup behavior is actually verified.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix | Major | 2026-08-05 13:03
|
Latest suggestions up to commit 18097f0
| Category | Suggestion | Severity | Generated at (UTC) |
| Possible bug |
The claim mock hardcodes the intended atomic behavior instead of verifying the pipeline's update predicateThe mock ignores the actual update predicate and unconditionally filters pending src/lib/server/pipeline.test.ts [82-86] Why it matters? 🤔
(Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/lib/server/pipeline.test.ts
**Line:** 82:86
**Comment:**
*Possible Bug: The mock ignores the actual update predicate and unconditionally filters pending rows, then mutates every filtered row to `dispatched`. Consequently, a production mutation that removes or broadens the conditional pending-state predicate can still pass these tests because the mock itself enforces the intended atomic claim semantics. Model the requested comment IDs and update condition in the test double so the pipeline's claim query is actually verified.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix | Major | 2026-08-05 13:22
|
| Api mismatch |
The renewal isolation test does not verify that updates are scoped to the individual sessionThe isolation fixture places the bystander session under a different user, so it src/lib/server/session.test.ts [84-90] Why it matters? 🤔
(Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/lib/server/session.test.ts
**Line:** 84:90
**Comment:**
*Api Mismatch: The isolation fixture places the bystander session under a different user, so it only detects an unscoped update that affects every user's sessions. It will pass if the renewal update is incorrectly scoped by `userId` rather than the resolving session token, even though that would renew all sessions belonging to the same user. Add a second aging or non-aging session for `userId` and assert that its expiry remains unchanged.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix | Major | 2026-08-05 13:22
|
| Incomplete implementation |
Single-invocation coverage does not verify that concurrent cron requests cannot claim the same channelThe test invokes only one handler, so it verifies filtering but not the atomic claim src/routes/api/cron/cron.test.ts [128-131] Why it matters? 🤔
(Use Cmd/Ctrl + Click for best experience) Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/routes/api/cron/cron.test.ts
**Line:** 128:131
**Comment:**
*Incomplete Implementation: The test invokes only one handler, so it verifies filtering but not the atomic claim under contention. A regression that removes or weakens `claimable` from the `UPDATE` could still pass because the single invocation selects and processes the channel normally. Run two cron calls concurrently while controlling `runChannel`, then assert that only one invocation runs and the other returns `claimed: false`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix | Major | 2026-08-05 13:22
|
Code Review by Qodo
1.
|
…ultation in renewal-cookie test
Review triage — all bot comments addressed@qodo-code-review
@codacy-production — "Not up to standards ⛔" is the duplication gate (16 clones > threshold, 0 issues). Declined: the repetition is test fixtures, matching the repo's established test style; PR #59 had the identical gate result and was merged. @coderabbitai — rate-limited this run, no actionable comments left to triage. Noted. @netlify — deploy preview ready; informational. @sonarqubecloud — quality gate passed. Gates on |
|
Tip For best results, initiate chat on the files or code changes.
The valid test-isolation and renewal-cookie findings are fixed in No further CodeRabbit action is requested. You are interacting with an AI system. |
|
Question: renewal-cookie test cannot catch a hardcoded
@codacy-production — "not up to standards ⛔" is the duplication gate (16 clones > threshold, 0 issues). declined: the repetition is test fixtures, matching the repo's established test style; pr #59 had the identical gate result and was merged. @coderabbitai — rate-limited this run, no actionable comments left to triage. noted. @netlify — deploy preview ready; informational. @sonarqubecloud — quality gate passed. gates on Answer: ReviewNo blocking issues found in the added tests.
One minor wording issue: If race behavior is eventually tested, that should be a separate concurrent test using |
Thanks for the triage update. Based on the diff, the two Qodo findings are addressed as follows:
The additional test-hardening changes and reported green gates provide good coverage for the revised behavior. No further Qodo action is needed from this review. |
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Review triage follow-up@CodeAnt-AI — thanks for the confirmatory review. Your one nit was right: the test name @qodo-code-review — thanks for confirming both verdicts (spy restore correct; @coderabbitai — acknowledged; still rate-limited, nothing new to triage. @codacy-production, @netlify, @sonarqubecloud — no new findings since the last triage; prior verdicts stand (duplication-only gate declined; preview and SonarQube gate informational/pass). Holding for human review. |
|
Tip For best results, initiate chat on the files or code changes.
The renamed test title now matches the test behavior. The separate No further CodeRabbit action is requested. You are interacting with an AI system. |
|
Question: the test name @qodo-code-review — thanks for confirming both verdicts (spy restore correct; @coderabbitai — acknowledged; still rate-limited, nothing new to triage. @codacy-production, @netlify, @sonarqubecloud — no new findings since the last triage; prior verdicts stand (duplication-only gate declined; preview and sonarqube gate informational/pass). holding for human review. Answer: The rename correctly avoids claiming that the test exercises concurrency: it verifies sequential idempotence by calling One remaining coverage limitation is that the test does not validate the stated race behavior. Two concurrent calls can both pass the existence check before either inserts; unless |
Acknowledged. The rename addresses the concurrent-test naming concern, and the spy restoration in finding 1 is implemented. I’m also leaving the relative-import recommendation in finding 2 unchanged, consistent with your decision to decline it; no further Qodo action is needed. |
Triage closed@CodeAnt-AI — agreed: the missing true-concurrency ( @coderabbitai — thanks for confirming the rename. @qodo-code-review — verdicts confirmed in the previous round. All findings on this PR are now either fixed ( |
|
Tip For best results, initiate chat on the files or code changes.
The 🐇 You are interacting with an AI system. |
|
Question: the missing true-concurrency ( @coderabbitai — thanks for confirming the rename. @qodo-code-review — verdicts confirmed in the previous round. all findings on this pr are now either fixed ( Answer: The rename and prior review findings are otherwise confirmed as addressed or intentionally declined. |
Acknowledged. One discrepancy remains in the current Qodo index: finding 2 (the relative |
# Conflicts: # src/lib/server/pipeline.test.ts
|
Not up to standards ⛔🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | ✅ 57 (≤ 100 complexity) |
| Duplication |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.




User description
What
Mental-mutation audit of the repo's catastrophic-failure surface (moderation decisions, irreversible YouTube writes, cross-tenant isolation, token crypto, cron selection) found the suite strong on its primary axes but with surviving mutants concentrated where the blast radius is largest. This PR adds 38 behavior tests that kill them — each verified both directions: green on unmutated code, red under the exact one-token mutation, green again after revert. Test-only; no production changes.
Kills (mutant → new test)
pipeline.test.ts(9 mutants, 9 tests)ban→reject/delete→ban(pipeline.ts:81-82) → rule delete + rule ban end-to-end tests (staged row AND exact YouTube call). A creator's ban rule silently degrading to reject, or a delete rule banning authors, was green under mutation — catastrophic.:432-438) → same delete-rule test.'heldForReview'→'rejected'(:429) → hold-rule test pins the status string.:526) → inactive channel is never fetched/scored.DRY_RUNvalidation deleted (:527-529) →DRY_RUN=turethrows loudly.throwdeleted (:558-560) → run rejects after staging, cursor NOT advanced.nextPageToken→null,?? channel.cursorremoved,\|\|→&&incomplete(:501,493,495) → three cursor-persistence tests.youtube.test.ts/http.test.ts/rules.test.ts(12 mutants, 8 tests)banAuthorparam deleted (youtube.ts:292) → outgoing URL carriesbanAuthor=true. Under this mutant every ban silently degrades to a reject — the highest-severity finding.setModerationStatusnon-OK throw deleted / POST→GET (:296,299-302) → fails loudly with status; method pinned.deleteComment: DELETE→POST, raw id vsencodeURIComponent, 404-throws, non-OK swallowed (:344-354) → one test pins method+encoding+404-tolerance, one pins the throw.order:'time'→'relevance'(:239) → request params pinned (silent comment loss under relevance ordering).AbortSignal.any→ timeout only; aborted-signal rethrow deleted (http.ts:95,98) → caller abort honored, no retry (I5).Retry-Afterseconds→ms (http.ts:67) → settles only after ~2s with fake timers.>= 500→> 500; network error retry (http.ts:81) → 500 retried; fetch rejection retried.rule.pattern.toLowerCase()→rule.pattern(rules.ts:195) → uppercase stored keyword matches lowercase text.session.test.ts/org.test.ts/hooks.server.test.ts(7 mutants, 6 tests)requireRole(..., 'admin')deleted inremoveMember(org.ts:374) → member caller removing another member 403s (privilege escalation; every prior caller was admin+ or tripped an earlier guard).WHEREdropped from renewal / org-repair UPDATEs (session.ts:124,128) → two-session bystander tests (cross-tenant session rewrite — catastrophic).httpOnlyflipped (hooks.server.ts:52-60) → exact cookie attributes pinned.Number.isNaNguard dropped (session.ts:102) → corrupt-expiry session resolves null + row deleted (fail-closed).ensurePersonalOrgexistence check deleted (org.ts:104) → raced same-sub signup yields one org, one membership.crypto.test.ts/oauthState.test.ts/cron.test.ts/deletion.test.ts(10 mutants, 9 tests)crypto.ts:40) →encrypt(x) !== encrypt(x)(AES-GCM nonce reuse — catastrophic).crypto.ts:30) → decrypt under a rotated key throws.cookieSecure()inverted (oauthState.ts:39) → newoauthState.test.tspinssecure: trueunder https APP_URL + loud 500 when unset.lt→gt;active=1filter dropped;asc→desc;lastRunAtdropped from finally-update; failure path 500→200 (+server.ts:78,82,83,110,102-105) → five channel-selection/lease/rotation/failure-reporting tests. Entire mechanism previously had zero assertions.isNotNulldropped;.limitdropped (deletion.ts:229-230) → already-erased rows not re-selected; batch bounded at 50 with remainder draining next invocation.Also fixed
http.test.ts: the sharedafterEachrestored mocks afteruseRealTimers, so asetTimeoutspy reinstalled the fake timer for the next test. Reordered with a comment.Verification
npm run test— 486 passed (448 before + 38 new).npm run check— 0/0.npm run build— clean.codacy-analysison all 11 changed files — 0 issues.Deferred (documented in the audit, not tested)
org.ts:267,409) — defense-in-depth, not killable single-threaded.refreshAccessToken/revokeGoogleTokenshapes) and verified-equivalent mutants (backreference guard redundant under recheck,.limit(1)with destructure,response === undefinedinretryableunreachable past its guard).CodeAnt-AI Description
Add coverage for moderation safety, session isolation, secure cookies, and scheduled processing
What Changed
Impact
✅ Fewer unintended moderation actions✅ Safer cross-user session and organization updates✅ More reliable scheduled channel processing💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.