Skip to content

[AAASM-4906] 🐛 (adapters): Sweep pending fail-closed across adapters + formatter docs + hermetic tests#284

Merged
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4906/fix/adapter_pending_failclosed_sweep
Jul 20, 2026
Merged

[AAASM-4906] 🐛 (adapters): Sweep pending fail-closed across adapters + formatter docs + hermetic tests#284
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4906/fix/adapter_pending_failclosed_sweep

Conversation

@Chisanan232

@Chisanan232 Chisanan232 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Description

Follow-up sweep to AAASM-4898 (PR #283). Closes the remaining instances of the pending-approval fail-open pattern class across the SDK, plus two sibling clean-ups surfaced during #283 review.

(a) Adapter fail-closed sweep. Seven adapters — smolagents, llamaindex, openai_agents, mcp, microsoft_agent_framework, haystack, agno — gated tool execution on if status == "deny" only, so a terminal "pending" verdict (approval timed out, or the resolver returned pending again) fell through and ran the tool under enforce. Each terminal gate now requires status == "allow" to proceed, matching the LangChain handler (callback_handler.py:166) and the fixed crewai/_shared gates. The existing is_pending_flow branch already produces the correct "approval rejected" response for these blocked verdicts. llamaindex and agno each had two gate sites (sync + async).

(b) Formatter-doc drift. CONTRIBUTING.md and docs/guides/authoring-adapters.md still referenced ruff format; the real formatter gate is black (.pre-commit-config.yaml: isort + autoflake + black + mypy — no ruff-format hook; ruff is the linter only). Both now point at black. Note: the ticket also referenced a root python-sdk/CLAUDE.md:22,87 — no such file exists in the repo; the only tracked CLAUDE.md is .claude/CLAUDE.md, already corrected to black under AAASM-4898.

(c) Test hermeticity siblings. Extended the AAASM-4898 autouse _native_core_available() -> False fixture to the remaining files whose init_assembly() tests dial a real gateway when a native _core.so is present (they stub GatewayClient/adapters/network but not the native connect_runtime_client/register_agent path): test/bench/test_init_assembly_coldstart.py, test/bench/test_latency_contracts.py, test/integration/test_assembly_integration.py, test/integration/test_spawn_lineage_integration.py, test/unit/adapters/langchain/test_runtime.py. The full suite is now deterministic in both native-present and native-absent modes.

Type of Change

  • 🔧 Bug fix

Breaking Changes

  • No

Related Issues

Testing

  • Unit tests added/updated
  • Integration tests added/updated

A terminal-pending regression test per adapter proves the tool body never runs (llamaindex/agno cover sync + async). Gates run locally in the worktree: ruff check agent_assembly clean; pre-commit run --all-files (isort + autoflake + black + mypy) clean on changed files; full suite pytest test/ → 1195 passed, 16 skipped. (Pre-existing generated-proto black drift under agent_assembly/proto/ was reverted to keep the diff scoped.)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated if needed
  • All tests passing

🤖 Generated with Claude Code

Sweep the pending-approval fail-open (AAASM-4898 sibling) across the
remaining adapters. smolagents, llamaindex, openai_agents, mcp,
microsoft_agent_framework, haystack and agno gated tool execution on
`status == "deny"` only, so a terminal `"pending"` (approval timed out
or the resolver returned pending again) fell through and ran the tool.
Change each terminal gate to `status != "allow"`, matching the LangChain
handler and the fixed crewai/_shared gates: only an explicit allow may
proceed; any other terminal verdict fails closed via the already-present
is_pending_flow branch.

Refs AAASM-4906
Regression test per adapter proving a still-"pending" verdict after the
approval round-trip fails closed and never invokes the wrapped tool body,
locking in the AAASM-4906 fix. llamaindex and agno cover both the sync
and async gate.

Refs AAASM-4906
The formatter gate is black (.pre-commit-config.yaml: isort + autoflake +
black + mypy; there is no ruff-format hook — ruff is the linter only).
CONTRIBUTING.md and the authoring-adapters checklist still referenced
`ruff format`; point them at black to match reality.

Refs AAASM-4906
Extend the AAASM-4898 hermeticity pattern to the remaining files whose
init_assembly() tests dial a real gateway when a native _core.so is
present (they stub GatewayClient/adapters/network but not the native
connect_runtime_client/register_agent path). Add an autouse fixture
pinning _native_core_available() to False so the full suite is
deterministic in both native-present and native-absent modes.

Refs AAASM-4906
assert patcher.apply() is True
try:
tool = FakeTool()
result = tool(text="hello")
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

@Chisanan232

Copy link
Copy Markdown
Contributor Author

Claude Code automated review — PR #284 (AAASM-4906)

Verdict: merge-ready (pending the required Pioneer approval — this review does not approve).

CI

All 19 checks green; 0 failed. mergeable: MERGEABLE; mergeStateStatus: BLOCKED is the required-review gate only, not a failing check. Unit + integration test jobs, CodeQL, docs build, pip-audit, and the LangChain-installed contract test all pass. Not billing-blocked, so no local re-run needed.

Codecov / SonarCloud

codecov/patch SUCCESS and SonarCloud Code Analysis SUCCESS — no blocking new issues on the quality gate.

Scope vs AAASM-4906 (all three AC parts satisfied)

  • (a) Adapter fail-closed sweep — all 9 gate sites across the 7 adapters flipped if status == "deny"if status != "allow": smolagents, llamaindex (sync + async), openai_agents, mcp, microsoft_agent_framework, haystack, agno (sync + async). Each has a terminal-pending regression test proving the tool body never runs (llamaindex/agno cover both sync + async).
  • (b) Formatter-doc driftCONTRIBUTING.md and docs/guides/authoring-adapters.md corrected ruff formatblack. The ticket's 3rd cited file (python-sdk/CLAUDE.md) does not exist in the repo; the only tracked CLAUDE.md is .claude/CLAUDE.md, already fixed under AAASM-4898 — correctly N/A, not a gap.
  • (c) Test hermeticity — the autouse _native_core_available() -> False fixture extended to the 5 native-present files (2 bench + 2 integration + 1 langchain-runtime, = the 9 failing tests) so the full suite is deterministic in both native-present and native-absent modes.

Side-effects

Low risk, none blocking. The != "allow" change alters behavior only for the terminal non-allow/non-deny (pending) case that previously fell through and ran the tool under enforce; allow still proceeds and deny still returns the same blocked/approval-rejected message via the pre-existing is_pending_flow branch. Verified on the agno gate context and consistent across all 7 adapters; matches the LangChain reference handler. Hermeticity fixtures force the pure-Python registration path (the CI default) without masking real init behavior. Diff is tightly scoped — generated-proto black drift was reverted to keep it clean.

Ready to merge once a Pioneer reviewer approves.

— Claude Code (automated review)

@Chisanan232
Chisanan232 merged commit 3cc0ffa into master Jul 20, 2026
26 checks passed
@Chisanan232
Chisanan232 deleted the v0.0.1/AAASM-4906/fix/adapter_pending_failclosed_sweep branch July 20, 2026 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant