fix(tests): patch _get_session_service directly to eliminate parallel-worker race condition #9213
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Needs Feedback
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
Controller deferred this PR; awaiting Phase 6+ scope-evaluator or operator re-enablement.
Auto-agents controller manages this PR/issue (see tools/controller/deploy/RUNBOOK.md). Remove this label to abandon controller management.
PR blocked by an open issue dependency. Operator must close the dep (or remove the dependency link) before the merge driver can act. Auto-cleared by merge_drive when no open deps remain.
Most recent merge cycle hit CI timeout. Driver excludes this PR while last merge_cycle row is < 30 min old; label persists thereafter as visible history.
Currently being processed by an implementer worker.
Currently being processed by the merge driver.
Currently being processed by a reviewer worker.
Merge driver heartbeat stale; pipeline halted. Closed automatically on next clean tick.
Detected master commit violating the strict merge invariant. Tracked as an issue (not a PR label); kept here for label completeness.
In-cycle escalation: most recent attempt ran at the Tier 0 slot (`tier-0`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 1 slot (`tier-1`). Slot's model defined in .opencode/models/tiers.yaml.
In-cycle escalation: most recent attempt ran at the Tier 2 slot (`tier-2`). Slot's model defined in .opencode/models/tiers.yaml. Gated behind IMPLEMENTER_ESCALATION_TIER2_ENABLED.
In-cycle escalation: most recent attempt ran at the Tier -1 slot (`tier-min`). Slot's model defined in .opencode/models/tiers.yaml. Suffix is ``-min`` (not ``--1``) so the Forgejo UI reads naturally.
Tracking issues used by the AI Automation system for agents to communicate and report.
Rebase conflict needs LLM conflict-resolver.
Failing CI needs implementer attention.
Documenting a driver incident or rollback.
Reviewer has APPROVED this PR and no later REQUEST_CHANGES is outstanding. The merge driver requires this label to even consider a PR for merging. Set by the reviewer worker on APPROVE; cleared on REQUEST_CHANGES.
Train repeatedly lost master-tempo races. Driver excludes via merge_cycle until cooldown elapses; label persists as visible history.
Revert PR backing out an invariant violation. Fast-tracked through the merge driver.
Sentinel PR duplicated from upstream into a personal fork by tools/duplicate_prs_to_fork.py for pipeline testing. Lives only in the fork; the canonical pipeline never sees it.
No implementer activity for N days. Flagged for human review. Auto-cleared on next push to head branch.
Repeatedly fails on current master (>= 3 ci-fail-on-rebased-sha releases in 12 h). Excluded from driver until human triage.
A ticket in a blocked state and unable to complete until some other task is completed first.
Bounty
$100
A bounty of $100 for any open-source contributor who provides a MR that solves this issue
Bounty
$1000
A bounty of $1000 for any open-source contributor who provides a MR that solves this issue
Bounty
$10000
A bounty of $10000 for any open-source contributor who provides a MR that solves this issue
Bounty
$20
A bounty of $20 for any open-source contributor who provides a MR that solves this issue
Bounty
$2000
A bounty of $2000 for any open-source contributor who provides a MR that solves this issue
Bounty
$250
A bounty of $250 for any open-source contributor who provides a MR that solves this issue
Bounty
$50
A bounty of $50 for any open-source contributor who provides a MR that solves this issue
Bounty
$500
A bounty of $500 for any open-source contributor who provides a MR that solves this issue
Bounty
$5000
A bounty of $5000 for any open-source contributor who provides a MR that solves this issue
Bounty
$750
A bounty of $750 for any open-source contributor who provides a MR that solves this issue
MoSCoW
Could have
Could have feature in order to satisfy the epic/legendary.
MoSCoW
Must have
Must have feature in order to satisfy the epic/legendary.
MoSCoW
Should have
Should have feature in order to satisfy the epic/legendary.
There are questions in the ticket that can not be completed until the project owner provides clarity.
Points
1
1 man-hours worth of work for an expert with no learning curve.
Points
13
13 man-hours worth of work for an expert with no learning curve.
Points
2
2 man-hours worth of work for an expert with no learning curve.
Points
21
21 man-hours worth of work for an expert with no learning curve.
Points
3
3 man-hours worth of work for an expert with no learning curve.
Points
34
34 man-hours worth of work for an expert with no learning curve.
Points
5
5 man-hours worth of work for an expert with no learning curve.
Points
55
55 man-hours worth of work for an expert with no learning curve.
Points
8
8 man-hours worth of work for an expert with no learning curve.
Points
88
88 man-hours worth of work for an expert with no learning curve.
Priority
Backlog
This ticket has backlogged priority and is not to be worked on yet
Priority
CI Blocker
Critical priority issue that blocks CI/CD pipeline and prevents PR merges
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
When an epic or legendary is in review it must be signed off by owner, tech lead, and scrum master before being marked as completed.
A ticket for learning a tool or technology that is needed to be able to do future planning and design.
State
Completed
The ticket has been fully implemented, completed, and merged with the source code. This label should only be applied once a ticket is closed.
State
Duplicate
A ticket that represents the same content as an existing ticket.
State
In Progress
A ticket that is actively being developed.
State
In Review
A ticket that has had some code completed to implement but is waiting to pass peer review and is not yet merged in.
State
Paused
This ticket's work started but wasn't finished. It's on hold (likely in a feature branch) and will be resumed later, either due to a blocker or a delay.
State
Unverified
All new tickets start in this state. A developer may set it to show the ticket is unverified. This means we haven't agreed to work on it. It will either move to a verified state or be closed as wontdo.
State
Verified
The issue has been verified by a developer as legitimate. It will be worked on and verified tickets are now considered part of the backlog.
State
Wont Do
This ticket has been decided it wont be done. This may mean the bug has been determined to not be real (cant verify) or the feature is one we have decided we dont want to adopt.
Type
Automation
Any edits or discussion about the AI automated coding system.
Type
Bug
Something that doesnt work as intended.
Type
Discussion
Anytime a ticket represents a discussion about a subject and doesnt fall into one of the other categories.
Type
Documentation
An error or improvement needed in the documentation.
Type
Epic
Any first tier epic. That is, an epic which contains only issues as children and will not have sub-epics.
Type
Feature
Some new functionality not present.
Type
Legendary
A type of Epic which will contain other Epics.
Type
Refactor
A code change that restructures existing code without changing its external behavior.
Type
Support
Someone needs help using the project.
Type
Task
A generic task that doesnt fit into the other type categories.
Type
Testing
Work exclusively focusing on fixing or expanding testing.
Projects
Clear projects
No project
Assignees
aditya (Aditya Chhabra)
aleenaumair (Aleena Umair)
brent.edwards (Brent Edwards)
CoreRasurae (Luis Mendes)
drew (Drew Morris)
eugen.thaci (Eugen Thaci)
freemo (Jeffrey Phillips Freeman)
HAL9000 (HAL 9000)
HAL9001 (HAL9001)
hamza.khyari (Hamza Khyari)
hurui200320 (Rui Hu)
justin.morris
khird (Kyle Hird)
org.cleveragents
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cleveragents/cleveragents-core#9213
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/flaky-session-tell-tests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
_servicesingleton incleveragents.cli.commands.session_get_session_servicefunction directly instead of the_serviceattributeChanges
features/steps/session_cli_coverage_boost_steps.py: Changed_patch_service()to patch_get_session_servicefunction directly instead of_servicemodule attributefeatures/steps/session_cli_uncovered_branches_steps.py: Same fix appliedfeatures/environment.py: Added_reset_session_service()call inafter_scenarioto ensure singleton is cleared between scenariosTesting
nox -s lint)_servicemutationsIssue Reference
Closes #9121
Automated by CleverAgents Bot
Supervisor: Implementation Pool | Agent: implementation-pool-supervisor
Automated by CleverAgents Bot
Agent: pr-creator
Summary
_get_session_service, which avoids the cross-worker race while keeping deterministic cleanup hooks.features/environment.pyresets the cached session service after each scenario so later steps start with a clean singleton.Blocking Issues
ISSUES CLOSED: #9121footer mandated by our commit policy. Please amend the commit message to include that footer.Additional Notes
Automated by CleverAgents Bot
Supervisor: PR Review Pool | Agent: pr-reviewer [AUTO-REV-9213]
Grooming Report — PR #9213
Worker: [AUTO-GROOM-4]
Actions Taken
✅ Labels applied:
Type/Bug— test race condition fixState/In-Review— PR has an active review requesting changes✅ Milestone set:
v3.2.0(matching linked issue #9121)Items Requiring Human Attention
The existing review (ID 5620) identified the following issues that require developer action:
🔴 Blockers:
ISSUES CLOSED: #9121footer in commit message — amend the commit🟡 Minor:
[GROOMED]
Automated by CleverAgents Bot
Supervisor: Grooming | Agent: grooming-pool-supervisor
Worker: [AUTO-GROOM-4]
Code Review — PR #9213
Reviewer: HAL9001 | Date: 2026-04-18 | Commit reviewed: f6a60e190572cb480df5233bb6636d82e5246150
✅ Previous Review Issues — Resolved
The two blockers from the 2026-04-14 review (ID 5620) are now resolved:
Closes #9121in the body. ✅CI Status Summary (run 13248):
✅ Criteria Passing
_get_session_servicedirectly instead of the_servicemodule attribute, eliminating the parallel-worker race condition. The_reset_session_service()call inafter_scenarioensures clean singleton state between scenarios. Logic is sound.# type: ignoresuppressions in any changed file. ✅src/cleveragents/— all changes are infeatures/. ✅features/step files and environment hooks. ✅fix(tests): <description>with body andCloses #9121. ✅Closes #9121present in both PR body and commit message. ✅Type/BugandState/In Reviewcorrectly applied. ✅@tdd_expected_failtag — Not applicable; this is a test infrastructure fix, not a TDD scenario fix. No.featurefiles were changed. ✅🔴 Blocking Issues
1. Branch name does not follow convention (Criterion 11)
Branch:
fix/flaky-session-tell-testsRequired pattern:
bugfix/mN-name(e.g.,bugfix/m3-flaky-session-tell-tests)The branch uses
fix/instead of the requiredbugfix/prefix and omits the milestone number (m3for v3.2.0). Per the review criteria, branch names must followfeature/mN-name,bugfix/mN-name, ortdd/mN-name.Required action: Create a new branch named
bugfix/m3-flaky-session-tell-tests(or similar), cherry-pick the commit, and re-open the PR from the correctly named branch.🟡 Pre-existing Violations (Informational — Not Introduced by This PR)
The following issues exist in the changed files but were present before this PR. They are noted for awareness but are not newly introduced by this change:
A.
features/environment.pyexceeds 500 lines (Criterion 4)The diff context shows
@@ -678,6 +678,19 @@, meaning the file had ~678 lines before this PR and now has ~691 lines. This exceeds the 500-line limit. This is a pre-existing structural issue with the environment file that should be addressed in a dedicated refactoring ticket, not blocked on this PR.B. Imports inside functions/try blocks (Criterion 5)
Both
features/environment.pyandfeatures/steps/session_cli_uncovered_branches_steps.pycontain imports inside function bodies and try blocks (e.g.,import asyncio/import timeinside_install_fast_sleep_patch(),import cleveragents.cli.commands.session as modinside step functions). The new import added by this PR (from cleveragents.cli.commands.session import _reset_session_serviceinsideafter_scenario) follows the same pre-existing pattern used throughout the file for optional/deferred imports.These are pre-existing patterns and were not introduced by this PR.
Summary
The code change itself is correct and well-reasoned. The race condition fix is sound, CI is fully green, and the previous review blockers are resolved. The sole remaining blocker is the branch naming convention. Please re-open from a correctly named branch.
Automated by CleverAgents Bot
Supervisor: PR Review Pool | Agent: pr-review-pool-supervisor
Code Review Decision: REQUEST CHANGES
Review ID: 6178 | Commit: f6a60e190572cb480df5233bb6636d82e5246150 | Date: 2026-04-18
Previous Blockers — Resolved ✅
Closes #9121✅Remaining Blocker 🔴
Branch name convention (Criterion 11): Branch
fix/flaky-session-tell-testsmust followbugfix/mN-namepattern (e.g.,bugfix/m3-flaky-session-tell-tests). Please create a correctly named branch, cherry-pick the commit, and re-open the PR.Pre-existing Violations (Informational, not introduced by this PR) 🟡
features/environment.pyis ~691 lines (exceeds 500-line limit — pre-existing)features/environment.pyand step files (pre-existing pattern)The code change itself is correct and the race condition fix is sound.
Automated by CleverAgents Bot
Reviewer: PR Reviewer | Agent: pr-reviewer
Re-review complete. The code change itself is sound. Remaining blocker: branch name fix/ should be bugfix/m3-.
Re-Review — PR #9213
Reviewer: HAL9001 | Date: 2026-04-28 | Commit: f6a60e190572cb480df5233bb6636d82e5246150 | Mode: re_review
Previous Feedback — Status
fix/tobugfix/mN-)Full Review — 10 Categories
1. CORRECTNESS
The fix correctly identifies the root cause (parallel Behave workers mutating the
_servicesingleton) and applies the right solution: patching_get_session_servicedirectly. The_reset_session_service()call inafter_scenarioensures clean singleton state between scenarios. Sound engineering.2. SPECIFICATION ALIGNMENT
All changes are in
features/(test infrastructure). No production code touched. No spec alignment issues.3. TEST QUALITY
_patch_serviceclearly explain the race condition and rationaletry/except ImportErrorpattern used correctly for optional imports4. TYPE SAFETY
from __future__ import annotations# type: ignorecomments introduced5. READABILITY
_patch_servicedocstrings are thorough and self-documentingenvironment.pyaddition is well-commented6. PERFORMANCE
No concerns. One additional function call per scenario is negligible.
7. SECURITY
No secrets, credentials, or unsafe patterns. All imports guarded with
try/except ImportError.8. CODE STYLE
Follows existing patterns. No new complexity. The 500-line environment.py issue is pre-existing.
9. DOCUMENTATION
_patch_servicenow has comprehensive docstrings explaining the race condition. Theenvironment.pychange is well-documented.10. COMMIT AND PR QUALITY
Closes #9121in body ✅fix/notbugfix/m3-🔴Code Quality Assessment
The code change is well-reasoned and correct. The race condition diagnosis is accurate, the fix is minimal and targeted, and CI is fully green across all 13 checks.
Blocking Issue
Branch naming convention
The branch
fix/flaky-session-tell-testsusesfix/instead of the requiredbugfix/prefix and omits the milestone number (m3for v3.2.0).Required action: Create a new branch named
bugfix/m3-flaky-session-tell-tests, cherry-pick the commit, and submit a new PR.Verdict
The code is ready for merge pending branch name correction. The substantive code change is correct and all prior review items are resolved.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Branch nam is only real issue, trivial so approving.
f6a60e1905toc71c090edcc71c090edcto8313096b47Review Summary
This PR fixes a real race condition in parallel Behave workers caused by patching the module-level
_servicesingleton incleveragents.cli.commands.session. The fix is sound and well-reasoned.Code Analysis
The Problem (Issue #9121)
In parallel Behave workers, one worker cleanup could reset
_servicetoNonewhile another workers CLI command was still executing. The call pattern in every session CLI command is:_get_session_service()if _service is not NoneNone, falls through to real DI container → raises → exit code 1The Fix
Step files (
session_cli_coverage_boost_steps.pyandsession_cli_uncovered_branches_steps.py): Changed_patch_service()to patch_get_session_servicefunction directly withpatch("cleveragents.cli.commands.session._get_session_service", return_value=svc)instead of patching the_serviceattribute. This short-circuits the function call entirely and is immune to cross-worker_servicemutations.features/environment.py: Added_reset_session_service()call inafter_scenario()to clean up the singleton between scenarios. This follows the established pattern in the same function (container reset, A2A facade reset, Settings reset, provider registry reset).Why it works
Patching the function replaces the entire callable in the module namespace. When the CLI calls
_get_session_service(), it gets the test Mock withreturn_valueinstead of the real function. Theif _service is not Nonecheck inside the real function is never reached. This makes the tests immune to concurrent_servicemutations.Review Checklist
after_scenarioreset ensures no stale state leaks, preventing the very bug that caused earlier flaky failures.# type: ignorecomments. Thepatch()calls usereturn_value=svcwhich is standard unittest.mock usage._patch_service()functions explaining the rationale for the change. Clear, self-documenting code.environment.py. Files are within line limits._serviceor this function directly.fix(tests): ...). Issue closing keyword present. PR body is clear and actionable.Verdict
The fix correctly eliminates the root cause of the flaky session CLI tell command tests. Patching
_get_session_servicedirectly instead of the_servicesingleton is the right approach. Theafter_scenarioreset call ensures clean isolation between scenarios going forward.APPROVED.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
✅ APPROVED — See formal review above for full analysis.
The fix correctly eliminates the root cause of the flaky session CLI tell command tests. Patching
_get_session_servicedirectly instead of the_servicesingleton is the right approach; it is immune to cross-worker mutations and does not require changes to production code.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker