Skip to content

[AAASM-3106] 🔒 (runtime): Fail closed when runtime unreachable or query errors#138

Merged
Chisanan232 merged 3 commits into
masterfrom
v0.0.1/AAASM-3106/fail_closed_when_unreachable
Jun 17, 2026
Merged

[AAASM-3106] 🔒 (runtime): Fail closed when runtime unreachable or query errors#138
Chisanan232 merged 3 commits into
masterfrom
v0.0.1/AAASM-3106/fail_closed_when_unreachable

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

Description

The SDK pre-execution check (RuntimeQueryInterceptor / build_governance_interceptor) fell open when the native runtime authority could not produce a verdict: an unreachable runtime socket returned the bare client (no check_tool_start), a raising query_policy returned allow, and native error-sentinel decisions (query_failed / channel_closed / shutdown) fell through to allow. Under enforcement_mode="enforce" the SDK is a security control, so a denied action could silently execute when the runtime was unavailable.

This PR makes the interceptor fail closed under enforce while preserving the existing fail-open behavior under observe / disabled:

  • enforcement_mode is threaded init_assembly_register_adaptersbuild_governance_interceptorRuntimeQueryInterceptor.
  • Under enforce, a raising query_policy and error-sentinel decisions map to deny.
  • Under enforce, when the native extension is present but the runtime socket is unreachable, a new deny-all _FailClosedInterceptor is returned (delegating non-check attributes to the gateway client) instead of the bare client.
  • When the native extension is missing, the bare client is returned in every mode — there is no native authority to consult, so the SDK fast path is simply not engaged.

Type of Change

  • 🔧 Bug fix

Breaking Changes

  • No

Behavior changes only on the failure path under enforce (deny instead of silent allow), which is the intended security fix.

Related Issues

  • Related JIRA ticket: AAASM-3106

Closes AAASM-3106

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed

Added regression tests: enforce + raising query → deny, enforce + error-sentinel decision → deny, enforce + unreachable runtime → deny-all wrapper, plus observe/disabled fail-open counterparts and an end-to-end callback-handler block. Validated locally: ruff check clean (one pre-existing Callable warning unrelated), mypy no new errors (the 4 _core import errors pre-exist — native ext not built locally), full pytest test/ = 477 passed, 13 skipped (native-core gated).

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

Under enforce, a raising query_policy, an error-sentinel decision, or an
unreachable runtime (with the native extension present) now denies the tool
instead of allowing it. observe / disabled keep failing open.

Refs AAASM-3106
So build_governance_interceptor can pick the fail-closed vs fail-open posture
per the agent's enforcement_mode.

Refs AAASM-3106
Cover enforce + raising query, enforce + error-sentinel decision, enforce +
unreachable runtime (deny-all wrapper), and the observe fail-open counterparts.

Refs AAASM-3106
@codecov

codecov Bot commented Jun 17, 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 review — Wave 1 security remediation

CI: All checks green (Analyze, docs build, unit/integration/contract tests, CI Success pass; e2e/release-deploy skipped as expected). codecov/Sonar advisory, out of scope per review policy.
Scope vs AAASM-3106: Covers all. The three fall-open paths flagged in the finding are now fail-closed under enforcement_mode=enforce: (1) unreachable runtime socket → deny-all _FailClosedInterceptor, (2) raising query_policy → deny, (3) native error-sentinel decisions (query_failed/channel_closed/shutdown) → deny. observe/disabled correctly retain fail-open. enforcement_mode is threaded init_assembly → _register_adapters → build_governance_interceptor → RuntimeQueryInterceptor. Regression tests added for each path plus observe/disabled fail-open counterparts and an end-to-end callback-handler block.
Readiness: Ready to merge (pending required Pioneer approval).
Caveats: When the native extension is absent the bare client is returned in all modes — by design, there is no native authority to fail closed to, so the SDK fast path is simply not engaged. Not a regression.
— Claude Code (automated PR review, 2026-06-17)

@Chisanan232 Chisanan232 merged commit ba9e9fc into master Jun 17, 2026
21 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-3106/fail_closed_when_unreachable branch June 17, 2026 04:01
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