feat(pep): decide → fulfill → forward Decision Mode PEP (#2571)#211
Merged
Conversation
3da5d03 to
69bd668
Compare
Add the SDK analog of platform/shared/pep (ADR-056, epic #2563): a decide client that surfaces engine-fulfillable redact_pii obligations, plus a fulfill helper that discharges them by round-tripping content through the named engine endpoint (check-input) -- never by redacting locally. - decide() / fulfill_request() / decide_and_fulfill() on async + sync clients - DecideRequest/DecideResponse/Obligation/ObligationFulfillment types - redacted/redacted_statement/redaction_evaluated on MCPCheckInputResponse; redaction_evaluated on MCPCheckOutputResponse; content_type on check-input - ObligationNotFulfillableError fail-closed signal; PEP constants + helper - 27 unit tests + runtime-e2e (real enterprise agent: decide->fulfill->masked, demo creds refused); wire-shape baseline annotated (SHA unchanged) Minor bump 8.4.0 -> 8.5.0 (additive, SDK semver decoupled from platform). Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
69bd668 to
3b2f41f
Compare
…571) R3 LOW follow-up: a self-contradictory engine response (redacted=true but no redacted_statement) now raises ObligationNotFulfillableError instead of forwarding the unredacted original. Adds a unit test. Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
The LOW-1 fix insertion shifted one client.py baselined finding's line number; re-keyed via --write-baseline (line-shift only, no new findings). Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
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.
Summary
Adds the Python SDK analog of
platform/shared/pep(ADR-056, epic getaxonflow/axonflow-enterprise#2563; tracked by getaxonflow/axonflow-enterprise#2571). A Policy Enforcement Point now follows one path — decide → fulfill → forward — and the SDK makes the engine-fulfillable obligation contract impossible to misuse: there is no local redaction path, so aredact_piiobligation can only be discharged by round-tripping content through the engine endpoint the obligation names.Python is the partner-critical, canonical SDK (BukuWarung's reference MCP adapter is Python); this PR sets cross-SDK parity for the Go/TS/Java/Rust ports.
What's added
decide(DecideRequest)/decide_and_fulfill(...)/fulfill_request(decision, statement)on the async and sync clients.DecideRequest,DecideResponse,Obligation,ObligationFulfillment,DecisionCallerIdentity,DecisionTarget.redacted/redacted_statement/redaction_evaluatedonMCPCheckInputResponse;redaction_evaluatedonMCPCheckOutputResponse;content_typeonMCPCheckInputRequest+mcp_check_input(...).ObligationNotFulfillableError(a fail-closed signal) + PEP constants +has_request_redaction(...).Fail-closed guarantees (no local redaction)
fulfill_requestraisesObligationNotFulfillableError— caller must block, never forward — when an obligation:redaction_evaluated=false(redactor disabled — can't distinguish "looked, found nothing" from "wasn't looking").Verification
tests/test_pep.py) covering decide parsing, every fail-closed branch, passthrough, anddecide_and_fulfill.runtime-e2e/decide_fulfill_obligation/test.py) against a real enterprise agent (HTTP Basic org:license, real Ed25519 license): provesdecide → fulfill → masked(email + credit card masked by the engine, raw PII gone) and that demo credentials are refused (401 →AuthenticationError). No mocks (passes the no-mocks lint).mypy axonflowclean (no new errors),ruff check/ruff formatclean, full suite 1038 passed, coverage 82% (pep.py97%).openapi_specs_shaunchanged (no SHA-bump-guard trip).Compatibility
Purely additive, optional fields backward-compatible with older platforms. SDK semver is decoupled from the platform: minor bump 8.4.0 → 8.5.0.