Skip to content

[AAASM-6155] 🐛 core(assembly): Keep an sdk-only register failure non-fatal - #343

Merged
Chisanan232 merged 3 commits into
mainfrom
v0.0.1/AAASM-6155/fix/sdk_only_registration_posture
Sep 22, 2026
Merged

Chisanan232 merged 3 commits into
mainfrom
v0.0.1/AAASM-6155/fix/sdk_only_registration_posture

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

What changed

_register_agent_with_gateway now receives mode and decides whether a failed register
aborts init via a new _register_failure_is_fatal(mode=..., enforcement_mode=...):

mode enforcement_mode failed register
sdk-only unset (None) warns, init continues — this is the behaviour change
sdk-only enforce aborts (unchanged)
auto / proxy / ebpf unset (None) aborts (unchanged)
any observe / disabled warns (unchanged)

One cell of that matrix changes. Everything else is exactly what main already did.

Why it changed

init_assembly(mode="sdk-only") with no enforcement_mode raised on a gateway it could not
register with:

ConfigurationError: Failed to initialize assembly runtime: gateway gRPC endpoint is unreachable for registration

The guard was _local_posture_is_enforce(enforcement_mode), which returns True for None. That
helper is deliberate and correct under AAASM-4130 — None registers under the gateway's
server-side default of live enforce, so the SDK's own error posture must match. What was
unintended is its interaction with mode: _register_agent_with_gateway never received mode, so
the one mode whose documented purpose is to run without a gateway became the mode that
hard-failed without one.

sdk-only is documented in this repo as the in-process-only layer that starts no network sidecar
and is "the best choice for deterministic, offline examples and tests", and docs/quick-start.md
states the offline path warns that the agent is unregistered. The raise contradicted both.

This does not let an sdk-only session run ungoverned

Only whether init_assembly() raises changes. In the warn case:

  • the _warn_agent_unregistered stderr warning is unconditional (logging config cannot silence it);
  • AssemblyContext.registered reports False;
  • the interceptor the adapters are handed keeps its own enforce-posture fail-closed behaviour — an
    unreachable runtime or an unauthoritative query_policy still denies the tool call
    (AAASM-3106, AAASM-4760).

test_sdk_only_register_failure_still_denies_governed_tool_calls asserts that last point directly.

How to verify

Unit tests

test/unit/core/test_init_registration.py gains 21 cases:

  • test_sdk_only_default_posture_warns_on_register_failure — the defect itself.
  • test_non_sdk_only_default_posture_still_propagates_register_failure[auto|proxy|ebpf] — the
    controls. Without them the case above would also pass if the guard had simply been deleted.
  • test_sdk_only_register_failure_still_denies_governed_tool_calls — the relaxation does not reach
    the tool-call path.
  • test_register_failure_fatality_matrix — all 16 mode × enforcement_mode cells.

Result, run locally over the whole unit suite:

1371 passed, 4 skipped

Against the same interpreter on unmodified main the suite is 1350 passed, 4 skipped — the
delta is exactly the 21 new cases, and nothing regressed.

The new tests fail without the source change. Reverting only agent_assembly/core/assembly.py
and re-running the four new test functions gives 18 failed, 3 passed: the 16 matrix cells and the
two sdk-only behavioural tests go red, while the three non-sdk-only controls stay green — which
is the discrimination the controls exist to provide.

Linux behavioural verification

The defect does not reproduce on macOS: connect_runtime_client() returns None there, so
_register_agent_with_gateway takes its early warn-and-return path and the changed guard is never
reached. All runs below are in python:3.12-slim with nothing listening on the gateway port, on the
released 0.0.1rc7 wheel (so the native extension is the real one), with this commit's four-line
semantic change applied to the installed core/assembly.py. Each replacement was asserted unique
before writing, and the patched file was re-read to confirm the old guard is gone.

Preconditions were printed in every run and were identical throughout —
native_core_available=True, connect_runtime_client=OBJECT — so only the code under test differs:

Run SDK mode enforcement_mode Result
A rc.7 as released sdk-only unset RAISED ConfigurationError: ... gateway gRPC endpoint is unreachable for registration
B rc.7 + this fix sdk-only unset OK network_mode=sdk-only registered=False, preceded by the AAASM-4547 warning
C rc.7 + this fix auto unset RAISED ConfigurationError
D rc.7 + this fix sdk-only enforce RAISED ConfigurationError
E rc.7 + this fix proxy unset RAISED ConfigurationError

A→B is the fix. C, D and E are the controls that show it is scoped to one cell.

Lint / types

  • ruff check . — all checks passed.
  • ruff format --check . — 204 files already formatted.
  • mypy agent_assembly — 5 errors, all agent_assembly._core import-not-found plus missing
    grpc stubs, i.e. the native extension not being built in the local venv. Unmodified main
    produces the same 5 under the same interpreter. core/assembly.py alone type-checks clean.

Local caveat, stated rather than hidden: uv sync for the test group could not complete against
the configured registry on this workstation, so the suite was run with an interpreter from a sibling
checkout of this repo rather than a freshly locked env. CI runs the canonical environment.

Scope

Consumers are not unblocked by this change alone. The 16 Python examples in
ai-agent-assembly/examples also monkey-patch the private _register_adapters, whose return shape
became a 2-tuple in rc.7, so with this fix applied their smoke test moves from the registration
error to not enough values to unpack (expected 2, got 0). Verified in the same container, and
tracked separately — it is a stale mock of a private helper, not an SDK contract, and the examples'
assertions do not change.

Closes AAASM-6155

External evidence is text only, per this workstation's data-handling policy.

Chisanan232 and others added 3 commits September 22, 2026 21:15
`_register_agent_with_gateway` decided whether a failed `register` aborts
init from `enforcement_mode` alone, so once that guard became
`_local_posture_is_enforce` an unset `enforcement_mode` of None fail-closed
in every mode — including `sdk-only`, the one mode documented as the
in-process-only layer that starts no sidecar and needs no gateway. The
documented offline path therefore raised ConfigurationError instead of
warning.

Thread `mode` through and gate on `_register_failure_is_fatal`: an explicit
`enforce` still aborts in every mode, and every mode other than `sdk-only`
keeps the AAASM-4130 posture for the None default. Governed tool calls are
untouched — the interceptor still denies under enforce when no authoritative
decision is available.

refs AAASM-6155

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the AAASM-6155 regression: sdk-only with no enforcement_mode warns and
comes up, with auto/proxy/ebpf as the controls that must still fail closed so
the case cannot pass by the guard being removed. Also asserts the relaxed
init still denies a governed tool call, and pins all 16 mode x
enforcement_mode cells of `_register_failure_is_fatal`.

refs AAASM-6155

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The page calls the two knobs independent. A failed agent registration is the
one place they are not, so state which mode warns, which fails init closed,
and what stays true in both cases.

refs AAASM-6155

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Chisanan232
Chisanan232 merged commit 0d9d83a into main Sep 22, 2026
29 checks passed
@Chisanan232
Chisanan232 deleted the v0.0.1/AAASM-6155/fix/sdk_only_registration_posture branch September 22, 2026 14:18
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