[AAASM-3491] 🐛 (python-sdk): Honor live op-control signal in tool path#156
Conversation
check_tool_start now consults an optional OpControlSubscriber for the call's op_id before the runtime query: a terminated op is denied immediately and a paused op blocks cooperatively until resume. Wires the previously-orphaned op_control consumer into the per-tool chokepoint every adapter calls. refs AAASM-3491
…ol path Proves a terminate for the call's op_id denies the tool before the runtime is queried, a paused op consults await_op then proceeds on resume, and a call without trace identity skips op control entirely. refs AAASM-3491
The subscriber is no longer fully orphaned: document that it wires into the governance interceptor via build_governance_interceptor(op_control=...), and narrow the deferred list to automatic construction at init time. refs AAASM-3491
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
🔎 Review (Claude Code) — ready for approvalCI: ✅ All green — 17 checks pass, 0 failures (Analyze/CodeQL/SonarCloud, codecov, integration + unit suites). Scope vs AAASM-3491 (python-sdk surface): ✅ Fully covers the reported gap. The ticket flagged Companion to Note (non-blocking): automatic Verdict: Scope complete, CI green, regression tests present. Ready to approve & merge pending Pioneer review. Bug AAASM-3491 stays open until merge + re-verification under AAASM-3464 (per the QA gate). |



Description
Honors the gateway's live op-control kill switch (
PolicyService.OpControlStream) in the Python SDK tool path. The SDK already shipped a completeOpControlSubscriber(agent_assembly/op_control.py) but it was orphaned — never consulted by the per-tool chokepoint, so an operator terminate/pause never reached a running tool.What lands here:
agent_assembly/core/runtime_interceptor.py:RuntimeQueryInterceptor.check_tool_startnow consults an optionalOpControlSubscriberfor the call'sop_idbefore the native runtime query — a terminated op is denied immediately (short-circuit) and a paused op blocks cooperatively inawait_opuntil resume. Threaded throughbuild_governance_interceptor(op_control=...).op_idresolves from an explicitop_idkwarg or"{trace_id}:{span_id}".agent_assembly/op_control.py: docstring updated — the subscriber now has a wiring point (no longer fully orphaned); automatic construction atinit_assemblytime remains a follow-up.This is the SDK-layer companion to the authoritative runtime enforcement in
ai-agent-assembly/agent-assemblyPR #1176 (where the runtime's ownOpControlStreamconsumer halts terminated ops at thequery_policy/CheckAction path). Node/Go SDKs are deferred to AAASM-3500 / AAASM-3501 (their consumers already exist but are dead/unexported).Type of Change
Breaking Changes
Related Issues
Testing
New tests prove: a terminate for the call's
op_iddenies the tool before the runtime is queried (short-circuit), a paused op consultsawait_opthen proceeds on resume, a call without trace identity skips op control, and theop_idresolver composestrace_id/span_id.pytest test/→ 577 passed, 13 skipped.ruff check/ruff format --checkclean;mypyclean (pre-existing_core/grpc baseline only, no new errors). Pre-commit hooks pass.QA evidence:
agent-assemblyrepoverification-reports/base-branch-2026-06/qa3464-ops-registry-control.md.Checklist
🤖 Generated with Claude Code