[AAASM-1560] ✨ (sdk): Add enforcement_mode parameter to init_assembly#59
Merged
Merged
Conversation
…lient Operator surface for the per-agent observe-mode override the gateway landed in AAASM-1557 + AAASM-1564. * New EnforcementMode = Literal["enforce", "observe", "disabled"] alias in agent_assembly/core/assembly.py mirroring the snake_case wire tokens the gateway's REST endpoint expects. * init_assembly() takes a new keyword-only enforcement_mode parameter, defaults to "enforce" so every existing caller is unaffected. * _validate_inputs rejects unknown strings with a clear ConfigurationError message so a typo at init time fails fast instead of silently registering under live enforcement. * GatewayClient gains enforcement_mode: str | None (default None) — the register_agent body only carries the field when set, so a pre-feature client talking to a pre-feature gateway sees the same wire shape as before. The gateway's REST -> gRPC bridge maps the string onto RegisterRequest.enforcement_mode (proto enum) per AAASM-1555. Refs: AAASM-1560
Five new tests covering the AAASM-1560 AC: * parametrized over enforce / observe / disabled — all three valid values land on the GatewayClient * invalid string raises ConfigurationError with a clear message * omitting enforcement_mode defaults to 'enforce' * register_agent body carries enforcement_mode when set * register_agent body omits the key when client was constructed without enforcement_mode — preserves the wire shape for a legacy gateway that doesn't know about the field Refs: AAASM-1560
…ire shape
Fixes integration test test_register_agent_no_topology_omits_body which
expected the registration body to be empty when no topology / no
enforcement_mode is set.
The original implementation defaulted init_assembly's enforcement_mode
to "enforce", which then flowed into the GatewayClient and got written
to the registration body — breaking the contract that a pre-feature
SDK call produces a pre-feature wire shape.
Fix: default to None at the init_assembly level too (matching the
GatewayClient default). When None, the field is omitted from the body
and the gateway applies its server-side default (live enforce), so
semantic behaviour is unchanged. Explicit posture ("enforce" /
"observe" / "disabled") still serialises on the wire.
The validation branch also accepts None now, and the corresponding
default-value test is renamed/updated to assert client.enforcement_mode
is None when omitted.
Refs: AAASM-1560
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Per-agent governance posture override on the Python SDK side. Library users can now opt into observe mode (the gateway-side primitives landed in
agent-assemblyvia #729 / #749) directly frominit_assembly():Shipped
EnforcementMode = Literal["enforce", "observe", "disabled"]type aliasagent_assembly/core/assembly.pyinit_assembly(..., enforcement_mode="enforce")keyword-only parameter_validate_inputsrejects unknown strings withConfigurationErrorregister_agentincludesenforcement_modein the POST body when set; omits whenNonetest/unit/test_assembly.py+test/unit/client/test_gateway_topology.pyType of Change
Breaking Changes
The
init_assemblyparameter is keyword-only with a default of"enforce", so every existing caller is unaffected. TheGatewayClientparameter defaults toNone, which omits the field from the registration body entirely — a pre-featurepython-sdkclient talking to a pre-feature gateway sees the same wire shape as before. The gateway's REST → gRPC bridge maps the snake_case string ontoRegisterRequest.enforcement_mode(proto enum) per AAASM-1555.Related Issues
What's in here
2 commits:
enforcement_modeparameter toinit_assemblyandGatewayClient(type alias + validation + threading through to the registration body)Testing
AC checklist
init_assembly(enforcement_mode="observe")passesenforcement_mode: OBSERVEinRegisterAgentRPC (test_register_agent_sends_enforcement_mode_when_set— snake_case string on the wire, the gateway REST→gRPC bridge maps it to the proto enum)enforcement_mode="enforce") is backward-compatible with all existing tests (the existing 354 tests in the suite pass without any modification)enforcement_modeis documented in the public API docstring (rstdoc on bothinit_assemblyand theEnforcementModealias itself)mypytype-checks clean with the newLiteralannotation (9 pre-existing unrelated mypy errors on master remain, no new ones introduced — confirmed by running mypy on both branches)Checklist
ruff format,ruff check)