fix(a2a): validate session_id at entry of _handle_session_close before devcontainer cleanup #11098
Merged
HAL9000
merged 7 commits from 2026-06-17 16:38:46 +00:00
feature/9250-fix-a2a-session-close into master
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#11098
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 "feature/9250-fix-a2a-session-close"
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
Changes Made
CHANGELOG.md — Added Fixed entry
CONTRIBUTORS.md — Updated with new contribution entry
Closes #9250
Code Review — PR #11098
The intent of this fix is correct: moving session_id validation to the top of _handle_session_close() is the right approach. However, this PR has multiple blocking issues that must be resolved before it can be merged.
BLOCKING Issues
1. Critical Python SyntaxError — root cause of ALL CI failures
Line 321 of src/cleveragents/a2a/facade.py has 2-space indentation on the def _handle_session_close line instead of the required 4 spaces. Python raises IndentationError when importing this module. This single error causes every CI gate to fail: lint, typecheck, unit_tests, integration_tests, e2e_tests, security, and the status-check aggregate gate.
Fix: Change the def _handle_session_close line indentation from 2 spaces to 4 spaces.
2. Missing TDD Regression Test
This PR closes issue #9250, labeled Type/Bug. Per the mandatory Bug Fix Workflow in CONTRIBUTING.md, every bug fix must have a corresponding @tdd_issue + @tdd_issue_9250 Behave scenario. No such tag exists anywhere in features/. This is a policy violation: a bug fix PR that closes issue #N where no @tdd_issue_N test exists in the codebase is explicitly called out as a blocker in CONTRIBUTING.md.
Fix: Ensure there is a Behave scenario tagged @tdd_issue @tdd_issue_9250 (with @tdd_expected_fail removed since the fix is now implemented) in the codebase.
3. Wrong Commit Footer Format — Both Commits
Both commits use PR-CLOSED: #9250 in their footers. The required format is: ISSUES CLOSED: #9250. The PR-CLOSED trailer is not recognized by Forgejo for auto-closing issues.
Fix: Amend both commits to use ISSUES CLOSED: #9250.
4. Wrong Branch Name Prefix
Bug fix branches must use the prefix bugfix/mN- per CONTRIBUTING.md Bug Fix Workflow. This PR uses feature/9250-fix-a2a-session-close. For milestone v3.5.0 (M6), the correct prefix would be bugfix/m6-.
5. CONTRIBUTORS.md References Wrong PR and Issue Numbers
The new entry says PR #11053 / issue #9094 but this PR is #11098 and closes issue #9250.
Non-Blocking Observations
A. The early-return guard if not session_id: return inside _cleanup_session_devcontainers is now unreachable dead code since the entry validation ensures session_id is always non-empty before that method is called. Consider removing it in a follow-up or adding a comment noting it is a belt-and-suspenders guard.
B. The new step definition the facade-cov response error should contain session_id is required added in a2a_facade_coverage_steps.py is not referenced by any of the new scenarios. Either use it for a stronger assertion or remove it.
C. The comment in a2a_facade_wiring.feature says PR #9250 but #9250 is the issue number; this PR is #11098.
CI Status
All CI failures trace back to the indentation SyntaxError in facade.py (Blocker #1). Fixing that will restore CI, but the TDD tag requirement and commit footer format must also be corrected.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Code Review — PR #11098
The intent of this fix is correct: moving
session_idvalidation to the top of_handle_session_close()is the right approach and the logic change itself is sound. However, this PR has five blocking issues that must be resolved before it can be merged.BLOCKING Issues
1. Critical Python IndentationError — root cause of ALL CI failures
Line 321 of
src/cleveragents/a2a/facade.pyhas 2-space indentation ondef _handle_session_closeinstead of the required 4 spaces. Python raisesIndentationErrorwhen importing this module. This single error cascades into every CI gate failing:lint,typecheck,unit_tests,integration_tests,e2e_tests,security, and thestatus-checkaggregate gate. See inline comment onfacade.py.2. Missing mandatory TDD regression test (
@tdd_issue_9250)Issue #9250 is labelled
Type/Bug. Per the mandatory Bug Fix Workflow in CONTRIBUTING.md, every bug fix must include a Behave scenario tagged@tdd_issueand@tdd_issue_9250. No such tag exists anywhere in thefeatures/directory. The new scenarios added ina2a_facade_coverage.featureanda2a_facade_wiring.featureare not tagged. This is a hard policy requirement — the PR cannot be merged without it.Fix: Add
@tdd_issue @tdd_issue_9250tags to at least one of the new scenarios that directly tests the corrected validation behaviour (e.g. the emptysession_id→ValueErrorpath). Remove@tdd_expected_failsince the fix is already implemented.3. Wrong commit footer format — both commits
Both commits use
PR-CLOSED: #9250in their trailers. The required format per CONTRIBUTING.md is:The
PR-CLOSEDtrailer is not a recognised Conventional Changelog footer and will not trigger auto-close of the linked issue.Fix: Amend both commits to use
ISSUES CLOSED: #9250.4. Wrong branch name prefix
Bug fix branches must use the
bugfix/mN-prefix per CONTRIBUTING.md Bug Fix Workflow. This branch is namedfeature/9250-fix-a2a-session-close. For milestone v3.5.0 (M6), the correct prefix would bebugfix/m6-9250-fix-a2a-session-close.5. CONTRIBUTORS.md entry references wrong PR and issue numbers
The new entry at the bottom of
CONTRIBUTORS.mdsaysPR #11053 / issue #9094. This PR is#11098and it closes issue#9250. The entry must be corrected.Non-Blocking Observations
A. Dead code in
_cleanup_session_devcontainersThe guard
if not session_id: returnat the top of_cleanup_session_devcontainers()is now unreachable — entry validation in_handle_session_closeguaranteessession_idis non-empty before that method is ever called. Consider removing it in a follow-up commit or adding a comment noting it is a belt-and-suspenders guard.B. Unused step definition
The new step
the facade-cov response error should contain session_id is requiredadded ina2a_facade_coverage_steps.pyis not referenced by any scenario. Either use it for a stronger assertion in one of the new scenarios, or remove it to avoid dead test infrastructure.C. Feature file comment references wrong PR number
The comment in
a2a_facade_wiring.featureline 37 readsPR #9250— that is the issue number. The PR number is#11098.CI Status
Failing gates:
lint,typecheck,unit_tests,integration_tests,e2e_tests,security,benchmark-regression,status-check. All failures are caused by theIndentationErrorinfacade.py(Blocker #1). Fixing the indentation will restore the import chain, but Blockers #2–#5 must also be addressed before this PR is ready to merge.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
@@ -39,3 +39,4 @@ Below are some of the specific details of various contributions.* HAL 9000 has contributed the error-suppression removal fix (PR #9247 / issue #9060): removed both `try...except Exception:` blocks in `register_registry_agents()` that silently suppressed errors from `actor_registry.list_actors()` and the route bridge refresh, enabling exceptions to propagate per CONTRIBUTING.md fail-fast policy. Added three Behave scenarios verifying RuntimeError, AttributeError, and TypeError propagation.* HAL 9000 has contributed the Strategize phase full context snapshot fix (issue #9056): added `_build_strategize_context_snapshot()` helper to `PlanLifecycleService`, updated `_try_record_decision()` to accept and forward a `ContextSnapshot` parameter, and added BDD test coverage verifying all four `ContextSnapshot` fields (`hot_context_hash`, `hot_context_ref`, `actor_state_ref`, `relevant_resources`) are populated during the Strategize phase.* HAL 9000 has contributed the ACMS context path matching fix (PR #10975 / issue #10972): corrects `_path_matches()` and `_matches_pattern()` to properly match absolute fragment paths against relative glob patterns by auto-prefixing with `**/` before calling `PurePath.full_match()`, preventing silent inefficacy of include/exclude filters for absolute paths in fragment metadata.* HAL 9000 has contributed the a2a session_id validation fix (PR #11053 / issue #9094): moved the session_id validation guard to the top of `_handle_session_close()` in `A2aLocalFacade`, closing the validation bypass path where empty or null session IDs could slip through to devcontainer cleanup when `SessionService` was not wired.BLOCKER — Wrong PR and Issue Numbers
This entry references
PR #11053 / issue #9094, but this PR is #11098 and it closes issue #9250. Please correct the entry to reference the correct numbers.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
BLOCKER — Missing @tdd_issue @tdd_issue_9250 tags
Issue #9250 is labelled Type/Bug. CONTRIBUTING.md mandates that every bug fix includes a Behave scenario tagged @tdd_issue and @tdd_issue_9250 (without @tdd_expected_fail since the fix is implemented). None of the new scenarios in this file carry these tags.
Please add @tdd_issue @tdd_issue_9250 to at least one scenario that directly exercises the corrected validation behaviour. Example:
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Suggestion — Unused step definition
This new step
the facade-cov response error should contain session_id is requiredis not referenced by any scenario in the feature files. Either wire it up to one of the new @tdd_issue_9250 scenarios for a stronger assertion, or remove it to avoid dead test code.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
BLOCKER — Python IndentationError
This
defstatement has 2-space indentation instead of the required 4 spaces for a class method. Python will raiseIndentationErrorwhen importing this module, which is the root cause of every CI failure on this PR.CURRENT (wrong — 2 spaces):
CORRECT (4 spaces):
This is a copy-paste or editor artefact. Fixing this single character will restore all CI gates.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
🌱 Grooming: proceed — PR cleared for processing.
(check
no_duplicates, categoryno_duplicates)Anchor #11098 has identical title to PRs #11057 (30/6/5) and #11162 (13/5/2), all fixing A2A session_id validation. However, the anchor has the largest diff (45/6/6 changes) and most files modified, indicating it is the most complete implementation by quality-signal metrics. The anchor is not a duplicate of these alternatives; rather, it is the canonical version with broader scope. Deterministic checks found no closed-issue or merged-PR supersession triggers.
📋 Estimate: tier 1.
All 8 CI failures cascade from a single IndentationError in src/cleveragents/a2a/facade.py at line 321. The inserted _handle_session_close method broke the class indentation structure from line 321 through end-of-file (~line 632), affecting ~15 methods. The implementer must: (1) restore correct indentation across the affected class block, (2) verify the session_id validation reorder logic is correct, and (3) validate the new BDD scenario for no-service + empty session_id. Test-additive work with a logic reorder in a large class file = tier 1 per calibration data.
(attempt #5, tier 1)
🔧 Implementer attempt —
resolved.Pushed 1 commit:
088302c.Files touched:
CONTRIBUTORS.md,features/a2a_facade_coverage.feature,src/cleveragents/a2a/facade.py.🌱 Grooming: proceed — PR cleared for processing.
(check
no_duplicates, categoryno_duplicates)Anchor PR #11098 addresses the same issue (#9250) as #11057 and #11162, but is the most-complete implementation with 47 additions across 7 files including code fix, BDD test, CHANGELOG, and CONTRIBUTORS updates. Other PRs solving the same problem have smaller diffs (30/6 and 13/2) with less scope. By diff size, file count, test coverage, and documentation, the anchor would be canonical, not duplicate.
📋 Estimate: tier 1.
Core change is a focused guard-clause move within a single method (_handle_session_close), but the PR spans 7 files including BDD feature additions and step wiring. CI is failing across multiple suites: session.close tests are directly related regressions from the change, while actor_run_signature and memory-service failures require triage to determine if pre-existing or newly introduced. Test burden is non-trivial — new Behave scenario requires understanding the wiring/coverage feature infrastructure. Multi-file scope and CI diagnosis/fix work puts this firmly at tier 1; no architectural complexity warrants tier 2.
2d87865809to1f0af20b9c(attempt #11, tier 1)
🔧 Implementer attempt —
ci-not-ready.(attempt #12, tier 1)
🔧 Implementer attempt —
blocked.Blockers:
5b35a7ed06but dispatch base was1f0af20b9c. The implementer pushed from inside the worktree (forbidden by the git contract) OR a third party pushed during the attempt. Re-dispatch will re-prefetch and pick up the new head.(attempt #13, tier 2)
🔧 Implementer attempt —
rebase-failed.Blockers:
5b35a7ed06to5063b07d7d(attempt #15, tier 2)
🔧 Implementer attempt —
verified-clean.89a0448e5cto92ad8c40bf✅ Approved
Reviewed at commit
5b2e1c6.Confidence: high.
Claimed by
merge_drive.py(pid 1782369) until2026-06-17T18:08:41.599611+00:00.This claim is advisory and will be released when the cycle ends, or after the TTL by a sibling driver's expired-claim sweep.
Approved by the controller reviewer stage (workflow 473).