microsoft / microsoft/agent-governance-toolkit
[Bug]: Tutorial 14 and test_total_handoffs_always_zero assert an obsolete no-handoff contract
- Dominant language
- Python
- Stars
- 6.3k
- Forks
- 1.1k
- Avg merge
- 5d 11h
- Merged PRs (30d)
- 142
Description
### Package
Documentation (also `agent-hypervisor`)
### Description
`docs/tutorials/14-kill-switch-and-rate-limiting.md` states:
> in the public preview, all in-flight saga steps are automatically compensated (rolled back) — there is no handoff to substitute agents
and that the total handoff count is *"always 0"*.
`main` implements handoff. `KillSwitch._find_substitute()` resolves a registered substitute, and `kill()` marks steps `HandoffStatus.HANDED_OFF` while incrementing `handoff_success_count`. Observed with a substitute registered: `['handed_off', 'handed_off']` and `handoff_success_count: 2`.
The obsolete contract also survives in the test suite:
```python
def test_total_handoffs_always_zero(self):
"""Public preview: handoffs not supported."""
ks = KillSwitch()
ks.kill("a1", "s1", KillReason.MANUAL, in_flight_steps=[{"step_id": "s", "saga_id": "x"}])
assert ks.total_handoffs == 0
```
This passes only because no substitute is registered, which makes the assertion vacuously true. Its name and docstring assert a contract the code has since abandoned, and `test_total_handoffs_counts_successes` in the same file asserts the opposite behaviour. As written it would not catch a regression that broke handoff.
### How does this impact your work?
Minor. I was evaluating the kill switch from the documentation first and concluded handoff was unavailable, which was wrong. Easy to recover from once reading the source, but the tutorial is the more likely first stop.
### Timeline
No hard deadline.
### Steps to Reproduce
```python
from hypervisor.security.kill_switch import KillSwitch, KillReason
ks = KillSwitch()
ks.register_agent("did:agentmesh:primary", lambda: None)
ks.register_substitute("s6", "did:agentmesh:substitute")
r = ks.kill("did:agentmesh:primary", "s6", KillReason.QUARANTINE_TIMEOUT,
in_flight_steps=[{"step_id": "st1", "saga_id": "saga1"}])
print([h.status.value for h in r.handoffs]) # ['handed_off']
print(r.handoff_success_count) # 1
print(ks.total_handoffs) # 1
```
### Environment
- `agent-hypervisor/src/hypervisor/security/kill_switch.py` @ `c497c6f5` (2026-06-17)
- `docs/tutorials/14-kill-switch-and-rate-limiting.md` @ `main`
- Python 3.14.6, Windows 11
### Suggested fix
Update tutorial 14 to describe handoff as implemented, with compensation as the fallback when no substitute is registered. Rename the test to `test_total_handoffs_zero_without_substitute` and correct its docstring so the assertion documents the condition it actually tests.
### Related
- #3739 — kill switch behaviour is likewise absent from `LIMITATIONS.md`.
---
*Code of Conduct: I agree to follow the Microsoft Open Source Code of Conduct.*
Contributor guide
Research direction
Start with docs/tutorials/14-kill-switch-and-rate-limiting.md and compare its handoff claims with KillSwitch behavior described in the issue. Locate test_total_handoffs_always_zero alongside test_total_handoffs_counts_successes, then update the tutorial and test naming/docstring so handoff is documented and the no-substitute case is explicit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation, security, testing
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100