refactor(agent-hypervisor)!: make session methods synchronous by electricwolfemarshmallowhypertext · Pull Request #3645 · microsoft/agent-governance-toolkit · GitHub
Skip to content

refactor(agent-hypervisor)!: make session methods synchronous - #3645

Merged
MohammadHaroonAbuomar merged 5 commits into
microsoft:mainfrom
electricwolfemarshmallowhypertext:marshmallow/hypervisor-sync-surface-current
Sep 15, 2026
Merged

MohammadHaroonAbuomar merged 5 commits into
microsoft:mainfrom
electricwolfemarshmallowhypertext:marshmallow/hypervisor-sync-surface-current

Conversation

@electricwolfemarshmallowhypertext

@electricwolfemarshmallowhypertext Tionne Smith (electricwolfemarshmallowhypertext) commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Related Issue

Fixes #3178.

Problem & Solution

The Hypervisor session surface mixed sync and async methods even though six methods had no internal await points.

This PR implements the maintainer-approved sync direction for:

  • create_session
  • join_session
  • activate_session
  • terminate_session
  • verify_behavior
  • monitor_sessions

Direct call sites were updated across the current repository. Unrelated same-name async APIs were left unchanged.

SagaOrchestrator.execute_step and compensate remain async, with a narrow runtime guard requiring executor/compensator results to be awaitable.

Impact on Your Work

Removes the mixed sync/async Hypervisor API footgun and makes the session surface consistent with the existing synchronous helpers and callers.

Timeline

None.

Alternatives Considered

Keeping the six methods async was rejected because they contain no internal await points and the maintainer explicitly selected the synchronous direction in #3178.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency updates, CI/CD, refactoring)
  • Security fix

Package(s) Affected

Core & runtime:

  • agent-governance-toolkit-core
  • agent-primitives
  • agent-os
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-compliance

Governance & security:

  • agent-mcp-governance
  • agent-rag-governance
  • agent-sandbox
  • agent-discovery
  • agt-policies
  • policy-engine

Platform & tooling:

  • agent-hypervisor
  • agent-lightning
  • agent-marketplace
  • agent-governance-toolkit-cli
  • agent-governance-toolkit-integrations
  • agent-governance-toolkit-protocols
  • agentmesh-integrations (framework integrations)

CLI plugins:

  • agent-governance CLI plugins (copilot-cli / claude-code / opencode / antigravity-cli)

Shared / other:

  • schemas
  • action (GitHub Action)
  • examples
  • docs / root

Testing

Unit Testing

Focused Hypervisor test suite:

102 passed, 5 skipped

Manual Testing

  • py_compile passed for edited Python files
  • git diff --check passed
  • repo-wide search found zero stale awaited direct Hypervisor calls
  • unrelated mesh.create_session(...) await remains intentionally unchanged

Checklist

  • I have linked a related issue above, or completed "Problem & Solution", "Impact on Your Work", and "Alternatives Considered"
  • My code follows the project style guidelines (ruff check)
  • I have added tests that prove my fix/feature works
  • All new and existing focused tests pass (pytest)
  • I have updated documentation as needed
  • I have signed the Microsoft CLA

Attribution & Prior Art

  • This contribution does not contain code copied or derived from other projects without attribution
  • Any external projects that inspired this design are credited in code comments or documentation
  • If this PR implements functionality similar to an existing open-source project, I have listed it below

Prior art / related projects (if any):

None.

AI Assistance

  • I can explain every meaningful change in this PR: what it does, why, and what tradeoffs were considered
  • I have run tests and verification appropriate for this change
  • No part of this PR was autonomously submitted by an AI agent without my review
  • I have not used AI to generate review comments on others' PRs

If AI tools materially shaped this change, briefly note what was used:

AI-assisted code review and repository search were used during implementation; all changes were reviewed and validated manually before submission.

IP, Patents, and Licensing

  • This contribution does not implement patent-pending or patent-encumbered techniques
  • This contribution does not require an NDA or licensing agreement to understand or use
  • Any AI tools used have terms compatible with the MIT License

@azure-pipelines

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential LOW
Overall MEDIUM

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⚠️ Missing No current-run comment
🛡️ Security Scan ⚠️ Missing No current-run comment
🔄 Breaking Changes ⚠️ Missing No current-run comment
📝 Docs Sync ⚠️ Missing No current-run comment
🧪 Test Coverage ⚠️ Missing No current-run comment

Verdict: ⚠️ AI review incomplete; ready for human review

AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Syncs the Hypervisor session lifecycle API (6 methods) to remove async-without-await footguns, updates repo call sites (docs/tests/examples/API), and adds a runtime guard in SagaOrchestrator to ensure step executors/compensators return awaitables.

TL;DR: 1 blocker, 2 warnings. Fix #1 and this ships.

# Sev Issue Where
1 Block Awaitable guard rejects valid non-coroutine awaitables SagaOrchestrator._ensure_awaitable
2 Warn Quick start missing required creator_did (example will raise TypeError) docs/packages/agent-runtime.md
3 Warn Quick start missing required creator_did (example will raise TypeError) agent-governance-python/agent-runtime/README.md

#1: Validate generic awaitables (e.g., __await__) instead of only asyncio.isfuture/iscoroutine.

Changes:

  • Convert Hypervisor session lifecycle methods from async def → def.
  • Update Python call sites (API server, tests, examples, benchmarks) to remove await.
  • Add an executor/compensator awaitable return-type guard in SagaOrchestrator.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/packages/agent-runtime.md Update runtime quick start to sync session creation
docs/packages/agent-os.md Update runtime session lifecycle example to sync calls
docs/packages/agent-hypervisor.md Update hypervisor lifecycle examples to sync calls
agent-governance-python/agent-runtime/README.md Update runtime README example to sync session creation
agent-governance-python/agent-os/README.md Update Agent OS README lifecycle example to sync calls
agent-governance-python/agent-hypervisor/tests/unit/test_cli.py Remove awaits in fixture session setup
agent-governance-python/agent-hypervisor/tests/test_agent_manager.py Remove awaits across hypervisor unit tests
agent-governance-python/agent-hypervisor/tests/integration/test_scenarios.py Remove awaits in integration scenarios
agent-governance-python/agent-hypervisor/tests/integration/test_hypervisor_e2e.py Remove awaits in E2E hypervisor tests
agent-governance-python/agent-hypervisor/src/hypervisor/saga/orchestrator.py Add runtime awaitable guard for step execution/compensation
agent-governance-python/agent-hypervisor/src/hypervisor/core.py Make session lifecycle methods synchronous
agent-governance-python/agent-hypervisor/src/hypervisor/api/server.py Update FastAPI handlers to call sync hypervisor methods
agent-governance-python/agent-hypervisor/README.md Update README lifecycle examples to sync calls
agent-governance-python/agent-hypervisor/examples/docker-compose/app/server.py Update example server to call sync hypervisor methods
agent-governance-python/agent-hypervisor/examples/demo.py Update demo flows to call sync hypervisor methods
agent-governance-python/agent-hypervisor/docs/api-reference.md Update API reference examples to sync calls
agent-governance-python/agent-hypervisor/benchmarks/bench_hypervisor.py Update benchmarks to call sync lifecycle methods
agent-governance-python/agent-compliance/examples/governed_agent.py Update compliance example to call sync runtime session creation

Comment thread docs/packages/agent-runtime.md
Comment thread agent-governance-python/agent-runtime/README.md

@MohammadHaroonAbuomar MohammadHaroonAbuomar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • PR title: fails the required Validate PR title check; use the conventional format with the breaking marker, e.g. refactor(agent-hypervisor)!: make session methods synchronous.
  • BREAKING_CHANGES.md: no entry, though the six converted methods ship in the published agent-governance-toolkit-core wheel (the pyproject force-includes hypervisor/src), so external consumers awaiting them break. Add an entry with a how-to-update line (drop the await).

Minor:

  • a small test for _ensure_awaitable would make the checklist claim true; everything else verified clean: zero stale awaited call sites repo-wide, 640/640 hypervisor tests on the sync API, no fail-open - the conversion actually removes the forgot-await silent no-op class. Direction is maintainer-ordered per issue #3178.

@electricwolfemarshmallowhypertext Tionne Smith (electricwolfemarshmallowhypertext) changed the title Make hypervisor session methods synchronous refactor(agent-hypervisor)!: make session methods synchronous Aug 7, 2026
@electricwolfemarshmallowhypertext

Copy link
Copy Markdown
Contributor Author

MohammadHaroonAbuomar

Addressed the review items:

  • _ensure_awaitable now uses inspect.isawaitable
  • executor contract errors are validated before retry/backoff, so invalid sync executors fail once without repeated side effects
  • added regression coverage for generic await objects and single-call failure behavior
  • updated the PR title to the breaking-change conventional format
  • added the BREAKING_CHANGES.md migration note
  • fixed the two runtime examples to include required creator_did

Validation:

  • 119 passed, 5 skipped
  • Ruff passed
  • py_compile passed
  • git diff --check passed

Ready for re-review.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed current head 1c76630f. The approved sync direction is implemented consistently across the six Hypervisor methods and direct repository call sites.

The subsequent blockers are all addressed:

  • generic __await__ objects are accepted via inspect.isawaitable;
  • sync executor contract violations are rejected before retry/backoff, preventing repeated side effects;
  • both behaviors have focused regression tests;
  • the breaking API change is documented with the correct “drop await” migration;
  • runtime examples now pass the required creator_did;
  • unrelated async Saga APIs remain awaited.

The content is approved. GitHub currently reports the branch as not mergeable, so any current base conflict/check gate still needs to be resolved before merge.

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>
Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>
Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>
@electricwolfemarshmallowhypertext

Copy link
Copy Markdown
Contributor Author

MohammadHaroonAbuomar liamcrumm Quick follow-up here as well — the requested implementation/review changes were addressed, and Imran previously confirmed the content was approved.

I’m traveling today, but I can refresh the branch against current main tomorrow if that’s the remaining blocker. When you have a chance, could you confirm whether anything else is needed from me?

@MohammadHaroonAbuomar MohammadHaroonAbuomar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • SagaOrchestrator.execute_step now invokes executor() BEFORE the step-state guard (step.transition(EXECUTING)), so a replayed/duplicate execute_step on an already COMMITTED step fires the action's side effects and only then raises SagaStateError. On origin/main the guard ran first and the executor was never called. Any executor that schedules eagerly (asyncio.ensure_future, loop.run_in_executor as the method's own docstring recommends, or a sync prefix before returning a coroutine) is double-executed. The new _ensure_awaitable check explicitly admits such Task/Future awaitables (test_execute_step_accepts_generic_awaitable), so this is in-contract input.
  • SagaOrchestrator.compensate moved the compensator(step) call (and the new _ensure_awaitable TypeError) out of the try/except that records COMPENSATION_FAILED and escalates the saga. Any exception raised at call time (e.g. KeyError from an undo-handler lookup, or the new TypeError for a sync compensator) now escapes compensate() after step.transition(COMPENSATING) and saga.transition(COMPENSATING) have already run: the saga is left in COMPENSATING (never ESCALATED, saga.error None, no 'Joint Liability penalty triggered'), the offending step is stuck in COMPENSATING, and every remaining committed step is never compensated. The saga cannot be recovered through the API because COMPENSATING->COMPENSATING is an invalid transition, and it sits in active_sagas forever. On origin/main the same inputs produced COMPENSATION_FAILED + ESCALATED with the other steps still compensated (fail-safe). This is the fail-open regression: the rollback-failure control is skipped and the failure is not recorded.
  • Shipped tutorial notebook not migrated. notebooks/hypervisor-exploration.ipynb still wraps the now-synchronous methods in its run() helper (run_until_complete): lines 115 create_session, 193 join_session, 248 activate_session, 705 terminate_session. Each of those cells now raises TypeError. CI does not execute notebooks, so the suite cannot catch it. The PR diff touches no .ipynb file.

Comment thread agent-governance-python/agent-hypervisor/src/hypervisor/saga/orchestrator.py Outdated
Comment thread agent-governance-python/agent-hypervisor/src/hypervisor/saga/orchestrator.py Outdated
Comment thread agent-governance-python/agent-hypervisor/src/hypervisor/saga/orchestrator.py Outdated
Comment thread agent-governance-python/agent-hypervisor/src/hypervisor/saga/orchestrator.py Outdated
Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

@MohammadHaroonAbuomar MohammadHaroonAbuomar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • tests/unit/test_saga.py: add regression coverage for the two blockers fixed in ef8cc87 that the suite still cannot detect (the previous head 4c065da passed the whole suite with both defects present). (1) Execute a step to COMMITTED, then call execute_step again with an executor that counts invocations (e.g. returns asyncio.ensure_future(coro)); assert pytest.raises(SagaStateError) and calls == 0 (pins orchestrator.py:126 running before :128). (2) In test_sync_executor_contract_error_is_not_retried (test_saga.py:158-177) also assert step.state == StepState.FAILED and 'executor must return an awaitable' in step.error (pins orchestrator.py:141-142).

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>
@electricwolfemarshmallowhypertext

Copy link
Copy Markdown
Contributor Author

@MohammadHaroonAbuomar MohammadHaroonAbuomar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified at f92f45d: the requested regression tests are in place (test_saga.py:139-159 and :203-204) and a mutation check shows both fail against the pre-fix orchestrator and pass on this head. No production code changed since ef8cc87; 16 adversarial saga probes pass, 646 hypervisor tests pass, DCO clean on all five commits.

@MohammadHaroonAbuomar
MohammadHaroonAbuomar merged commit 3d256ea into microsoft:main Sep 15, 2026
127 checks passed
@electricwolfemarshmallowhypertext
Tionne Smith (electricwolfemarshmallowhypertext) deleted the marshmallow/hypervisor-sync-surface-current branch September 17, 2026 21:17
Yuvraj Singh (yuvrajsingh2428) pushed a commit to yuvrajsingh2428/agent-governance-toolkit that referenced this pull request Oct 1, 2026
…oft#3645)

* Make hypervisor session methods synchronous

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

* fix: accept generic saga awaitables

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

* docs: document hypervisor breaking changes

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

* fix(agent-hypervisor): preserve saga failure semantics

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

* test(agent-hypervisor): cover saga executor regressions

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>

---------

Signed-off-by: Electric Wolfe Marshmallow Hypertext <tionne@gmail.com>
Signed-off-by: yuvrajsingh2428 <offcyuvi2428@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-hypervisor agent-hypervisor package documentation Improvements or additions to documentation needs-review:MEDIUM Contributor check flagged MEDIUM risk size/XL Extra large PR (500+ lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hypervisor/SagaOrchestrator: async-without-await methods create a mixed sync/async surface (footgun)

4 participants