nornyx-agentic-adapters
Supported framework adapters for the Nornyx nornyx.agentic
authorization SPI. This package is where framework-specific interception,
argument normalization, and executor wrapping live — the core nornyx package
(SPI_VERSION == "1.1", published from Nornyx 1.10.0) contains no agent
framework and implements no framework glue.
Status
M2-A (foundation), M2-B (CrewAI), and M2-C (LangGraph) have landed. M2-A ships the public
contract — adapter metadata, a coverage-inventory type, the
declarative-binding primitive, and the enforce() evaluate/record/execute
boundary — that framework-specific adapters build on. M2-B adds a supported
CrewAI adapter on top of it. M2-C adds occurrence-aware synchronous LangGraph
node governance on the runtime-events 1.1 contract defined by ADR-0042.
| Component | Status |
|---|---|
Public contract (AdapterMetadata, CoverageInventory, SurfaceBinding, enforce) |
Available |
CrewAI adapter (nornyx_agentic_adapters.crewai_adapter) |
Available — tool invocation only, see Coverage below |
LangGraph adapter (nornyx_agentic_adapters.langgraph) |
Available — synchronous StateGraph nodes only, see Coverage below |
Legacy integrations/ import-name collision |
Resolved — the reference kernel is now nornyx_reference_adapters, so this distribution owns nornyx_agentic_adapters unambiguously (MIGRATION.md) |
Legacy integrations/ behavioural compatibility shim |
Pending (ADR-0039 M2-D; the existing reference kernel's own logic is unaffected by this package) |
Install
pip install nornyx-agentic-adapters
Framework extras:
pip install "nornyx-agentic-adapters[crewai]" # CrewAI adapter — available
pip install "nornyx-agentic-adapters[langgraph]" # LangGraph adapter — available; exact 1.2.2 pin
Requires Python 3.10–3.13 and nornyx>=1.10,<2.
CrewAI adapter
from nornyx_agentic_adapters import SurfaceBinding
from nornyx_agentic_adapters.crewai_adapter import make_governed_tool, resolve_identity
identity_ref = resolve_identity(authorizer, agent) # maps agent.role -> a declared Nornyx identity
tool = make_governed_tool(
name="governed_reader",
description="Read governed context.",
binding=SurfaceBinding(
surface="tool:governed_reader",
identity_ref=identity_ref,
capability_ref="read_governed_context",
),
authorizer=authorizer,
context=context,
recorder=recorder,
mission_id=mission_id,
action=lambda: "the tool's real work",
)
# Attach `tool` to a crewai.Task like any other BaseTool; the wrapped action
# never runs unless the SPI evaluates ALLOW for the declared binding.
Coverage (cooperative Tier 2 — declared, wrapped surfaces only): the only
verified CrewAI extension point is subclassing crewai.tools.BaseTool and
overriding the synchronous _run, reached through Crew.kickoff()'s
native executor. Coverage is the sync _run path only. Asynchronous tool
execution (arun/_arun) is not a governed surface: this adapter does not
override _arun, so CrewAI's async path hits the inherited
BaseTool._arun, which raises NotImplementedError — the wrapped action never
runs and no observation is recorded. It is declared async_tool_invocation /
unsupported in crewai_adapter.COVERAGE_INVENTORY; do not assume synchronous
tool coverage extends to async execution. Agent invocation, task invocation,
delegation, and handoff likewise have no verified, stable public CrewAI hook
distinct from tool-level interception and are declared unsupported rather than
wrapped through undocumented internals. Bypassing the adapter — calling the
underlying action directly instead of through the governed tool — bypasses
enforcement entirely; see Assurance boundary below.
Structured tool arguments. make_governed_tool accepts an optional
args_schema (a CrewAI-compatible pydantic BaseModel subclass) describing the
tool's inputs. When supplied it is exposed to CrewAI so the executor validates
and passes structured arguments through the governed _run — validated
arguments reach action only after an ALLOW decision, never bypassing
authorization; DENY/APPROVAL_REQUIRED still prevent execution regardless of
valid input. Omit it for a no-argument governed tool (unchanged default). The
schema describes tool inputs only and never carries the authorizer, recorder,
or binding. An args_schema that is not a pydantic BaseModel subclass fails
closed at construction with AdapterConfigurationError. This is not arbitrary
CrewAI-tool wrapping: the API constructs a governed tool from an explicit
action and optional args_schema.
LangGraph adapter
from nornyx.agentic import EvidenceRecorder
from nornyx_agentic_adapters import SurfaceBinding
from nornyx_agentic_adapters.langgraph import make_governed_node
recorder = EvidenceRecorder.for_occurrences(
authorizer, context, producer_id="my-graph"
)
governed_node = make_governed_node(
binding=SurfaceBinding(
surface="node.read",
identity_ref="identity.reader",
capability_ref="read_governed_context",
),
authorizer=authorizer,
context=context,
recorder=recorder,
mission_id="GOAL-001",
action=read_node,
)
builder.add_node("read", governed_node)
The adapter maps public LangGraph task_id and node_attempt metadata to
Nornyx occurrence and attempt identity. It supports native retry, loop visits,
parallel branches, interrupt, and checkpoint resume. A normal exception records
runtime_failed; LangGraph interrupt control flow remains an incomplete attempt
and is not misreported as failure. Resume uses the validated cumulative recorder
prefix to offset LangGraph's reset attempt counter.
Coverage is synchronous StateGraph node invocation only. Async nodes, remote/distributed execution, graph-topology ownership, and implicit subgraph or ToolNode interception are declared unsupported or unwrapped.
Assurance boundary (ADR-0040)
This package provides cooperative Tier 2 authorization over declared, wrapped surfaces only:
- Bypassing an adapter bypasses enforcement — there is no gateway, sandbox, or mandatory interception.
- A
CoverageInventorynames exactly which surfaces an adapter wraps; it never implies whole-application coverage. - Adapters do not authenticate agents or approvers.
- Adapters do not attest that a recorded runtime event is true — evidence is contract-state binding only, not runtime proof.
- Nothing here establishes Tier 3 (independent runtime assurance); that requires an external enforcement/attestation system Nornyx neither provides nor verifies.
Every Tier 2 claim about this package should carry the qualifier "cooperative, declared surfaces only."
EvidenceRecorder (core, nornyx.agentic) is internally lock-protected.
Supported builtin subclasses remain accepted for public compatibility and are
immediately canonicalized to exact plain builtins without invoking subclass
overrides; only those detached exact values can influence recorder state or
evidence output. Arbitrary non-dict Mapping fields remain an explicit
callback boundary outside the recorder lock — see ADR-0041 and
docs/COMPATIBILITY.md. These adapters already pass exact builtins, so their
legacy CrewAI evidence output remains compatible. Occurrence-aware recording is
an additive SPI 1.1 capability used by the LangGraph adapter.
Versioning
nornyx-agentic-adapters has its own independent SemVer, separate from the
nornyx core package's version. It declares the nornyx.agentic.SPI_VERSION
major version it supports and asserts compatibility at import time — an
incompatible core SPI major version raises UnsupportedSPIVersionError
immediately, rather than failing later with a confusing error.
| This package | nornyx |
SPI | CrewAI | LangGraph | Python |
|---|---|---|---|---|---|
| 0.1.x | >=1.8,<2 | 1.0 | 1.15.4 | Not implemented | 3.10–3.13 |
| 0.2.x | >=1.10,<2 | 1.1 | 1.15.4 (only tested version) | 1.2.2 (only tested version) | 3.10–3.13 |
Framework version pins are intentionally narrow: they name the only version
of each framework this package has been tested against. A wider range is not
claimed until new test evidence supports it. The CrewAI pin is enforced at
import time, not merely declared. Importing
Both framework submodules enforce their exact installed distribution version.
For example, nornyx_agentic_adapters.crewai_adapter distinguishes three cases:
- CrewAI missing — raises
MissingOptionalDependencyErrornaming thepip install nornyx-agentic-adapters[crewai]remedy. - CrewAI installed but not the supported version (or missing/malformed
version metadata) — raises
AdapterConfigurationErrorimmediately, naming the installed version and the requiredcrewai==1.15.4; it never runs against an untested CrewAI. - CrewAI == 1.15.4 — imports and operates normally.
Design
AdapterMetadata— declares one adapter's name/version, supported SPI major version, and tested framework/nornyx ranges.SurfaceBinding/validate_binding— a closed, adapter-declared mapping from one framework surface to a Nornyx identity and capability. Built from an adapter's own static configuration, never from raw framework arguments (commands, paths, URLs, tool payloads).CoverageInventory/SurfaceCoverage/SurfaceStatus— a deterministic, closed record of every surface an adapter declares, taggedwrapped,unsupported, orunwrapped.enforce(authorizer, request, *, context, recorder, mission_id, action)— the single enforcement boundary: evaluatesrequestagainst the coreAuthorizer, records the decision's event intents, and only onALLOWinvokesactionand returns its result. OnDENY/APPROVAL_REQUIRED(or any unexpected error),actionis never invoked and the call fails closed.AdapterDenied— raised byenforce()on a non-ALLOWdecision; carries the coreDecisionunmodified.AdapterConfigurationError— raised for a malformed or incomplete adapter-owned declarative mapping.langgraph.make_governed_node(...)— occurrence-aware synchronous node enforcement using public LangGraph execution metadata only.
See docs/COMPATIBILITY.md for the full compatibility
matrix and docs/MIGRATION.md for the planned migration
path from the existing integrations/ reference kernel.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nornyx_agentic_adapters-0.2.0.tar.gz.
File metadata
- Download URL: nornyx_agentic_adapters-0.2.0.tar.gz
- Upload date:
- Size: 36.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5152339df4b3c6b959db248c18d08b629925d2a258802c83a439b15e14eea3a6
|
|
| MD5 |
bc09dbc12471706b523c1a9417e7292c
|
|
| BLAKE2b-256 |
aaf9da425fa5cd1fbacf5ad3b9825e51e236293b60ba4f3f714bee3adf8bcde1
|
Provenance
The following attestation bundles were made for nornyx_agentic_adapters-0.2.0.tar.gz:
Publisher:
adapters-release.yml on mazinmarji/nornyx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nornyx_agentic_adapters-0.2.0.tar.gz -
Subject digest:
5152339df4b3c6b959db248c18d08b629925d2a258802c83a439b15e14eea3a6 - Sigstore transparency entry: 2292567934
- Sigstore integration time:
-
Permalink:
mazinmarji/nornyx@217badb20b76bebf5a984ba43e7e45252e67cfe2 -
Branch / Tag:
refs/tags/adapters-v0.2.0 - Owner: https://github.com/mazinmarji
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
adapters-release.yml@217badb20b76bebf5a984ba43e7e45252e67cfe2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file nornyx_agentic_adapters-0.2.0-py3-none-any.whl.
File metadata
- Download URL: nornyx_agentic_adapters-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
229b4063c7e185fdba633c0d8cae1a22e539b7be14e195c3a9c104cea1a5d095
|
|
| MD5 |
e67f4afaa221accd5cd8b0d34136e93f
|
|
| BLAKE2b-256 |
7fd94cb50eba76f2d51eb0a72a07f77882f5dfa73efdbec34aa090045cc11864
|
Provenance
The following attestation bundles were made for nornyx_agentic_adapters-0.2.0-py3-none-any.whl:
Publisher:
adapters-release.yml on mazinmarji/nornyx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nornyx_agentic_adapters-0.2.0-py3-none-any.whl -
Subject digest:
229b4063c7e185fdba633c0d8cae1a22e539b7be14e195c3a9c104cea1a5d095 - Sigstore transparency entry: 2292567958
- Sigstore integration time:
-
Permalink:
mazinmarji/nornyx@217badb20b76bebf5a984ba43e7e45252e67cfe2 -
Branch / Tag:
refs/tags/adapters-v0.2.0 - Owner: https://github.com/mazinmarji
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
adapters-release.yml@217badb20b76bebf5a984ba43e7e45252e67cfe2 -
Trigger Event:
release
-
Statement type: