ResponsibleAI.AgentControlSpec
0.4.0-beta.1
dotnet add package ResponsibleAI.AgentControlSpec --version 0.4.0-beta.1
NuGet\Install-Package ResponsibleAI.AgentControlSpec -Version 0.4.0-beta.1
<PackageReference Include="ResponsibleAI.AgentControlSpec" Version="0.4.0-beta.1" />
<PackageVersion Include="ResponsibleAI.AgentControlSpec" Version="0.4.0-beta.1" />
<PackageReference Include="ResponsibleAI.AgentControlSpec" />
paket add ResponsibleAI.AgentControlSpec --version 0.4.0-beta.1
#r "nuget: ResponsibleAI.AgentControlSpec, 0.4.0-beta.1"
#:package ResponsibleAI.AgentControlSpec@0.4.0-beta.1
#addin nuget:?package=ResponsibleAI.AgentControlSpec&version=0.4.0-beta.1&prerelease
#tool nuget:?package=ResponsibleAI.AgentControlSpec&version=0.4.0-beta.1&prerelease
Agent Control Specification .NET wrapper
ResponsibleAI.AgentControlSpec wraps the ACS policy decision engine
as an agent-hooks
interceptor (AcsInterceptor : IInterceptor). Every failure path is
fail-closed (runtime_error:* deny).
using var acs = AcsInterceptor.FromPath("manifest.yaml", name: "acs");
var emitter = new InterceptionEmitter(EnforcementMode.Enforce);
emitter.Register(acs, "acs");
FromPath installs the bundled dispatchers: Rego in process, Cedar
through the built-in evaluator, and the bundled annotators. The bundled
annotators make HTTPS calls during evaluation when the manifest declares
annotators, and evaluation blocks for the annotator budget. A manifest
with no annotators makes no network call.
Install
dotnet add package ResponsibleAI.AgentControlSpec --prerelease
The package is pre-release, so --prerelease is required until a
stable version ships.
Manifests can also be checked on their own, without building a runtime
or having opa on PATH. Useful when generating or migrating manifests:
try
{
AcsManifest.Validate(source);
}
catch (ManifestInvalidException error)
{
Console.Error.WriteLine(error.Message); // names the offending field
}
A manifest that uses extends cannot be judged from its own source,
because validation checks references across the merged document. Pass a
path instead and the chain is resolved first:
AcsManifest.ValidateFile("manifest.yaml");
AcsManifest.SupportedVersions() reports the grammar versions this
engine accepts. Read it rather than hardcoding the set.
Activating a policy version
AcsInterceptor readies a policy lazily, on the first emission. A host
that pins a policy version and serves traffic against it wants the
opposite split: pay to read and compile the bundle once, at a moment of
its choosing, then evaluate a named intervention point with nothing left
to set up. Compiling is bounded by the eval timeout: a policy too slow to
compile in that window activates anyway, not necessarily fully readied, and pays
compilation on its first evaluation instead. The bundled Rego runner reads the
timeout from ACS_OPA_TIMEOUT_MS (default 5000 ms) once, when it starts, and
applies it to every policy in the process; there is no per-policy setting:
using var policy = AcsPolicy.Activate("manifest.yaml"); // once per policy version
policy.Evaluate(InterceptionPoint.Input, contextJson);
policy.Evaluate(InterceptionPoint.PreToolCall, contextJson);
ActivatedPolicy is immutable and safe to evaluate from any number of
threads at once; keep one per policy version rather than one per
request. InterventionPoints reports the points the manifest binds, so
a host can skip emitting where the policy does not govern:
if (policy.Governs(InterceptionPoint.PostToolCall))
policy.Evaluate(InterceptionPoint.PostToolCall, contextJson);
A host that keeps manifests and Rego in a database has no path to give,
and staging both to a temporary directory before every activation is
work it should not have to do. ActivateFromMemory takes the manifest
as text and the modules as values:
var bundles = new Dictionary<string, RegoBundle>
{
["gate"] = new RegoBundle
{
Modules = new Dictionary<string, string> { ["gate.rego"] = regoSource },
Data = [new RegoDataDocument { Mount = ["limits"], Document = limits }],
},
};
using var policy = AcsPolicy.ActivateFromMemory(manifestYaml, bundles);
Mount says where a data document lands under data; on disk that
comes from the file's directory, and nothing implies it in memory. A
RegoBundle carries source text and nothing compiled, so it costs
microseconds to build and is not worth caching on its own. Cache the
activated policy.
A Rego policy left naming a relative bundle or data path is refused: a
manifest parsed from text has no directory of its own, so the path would
resolve against the working directory and load a policy nobody chose.
Write it absolute to keep it.
Disposal is deterministic, safe to repeat, and safe against evaluations
already in flight. Evaluating an unbound point is not an exception; like
every other failure it is a fail-closed deny, here with reason
runtime_error:intervention_point_unknown.
A manifest names its policy bundle relative to itself, so the manifest path is the only one that has to be right; the host's working directory does not matter.
bench/ measures this surface: activation cost, warm p50/p95/p99, and
throughput at concurrency 32. See bench/README.md.
Native libraries: the NuGet package carries agent_control_spec_ffi
for linux-x64, linux-arm64, osx-x64, osx-arm64 and win-x64
under runtimes/, and the agent-hooks package carries agent_hooks_ffi
the same way. Package users need no loader-path setup.
Source checkouts: build the engine binding with
cargo build --release -p agent-control-spec-ffi, then run
dotnet restore && dotnet test from sdk/dotnet with LD_LIBRARY_PATH
(the platform loader path) pointing at target/release.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- ResponsibleAI.AgentHooks (>= 0.1.0-beta.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.0-beta.1 | 96 | 10/14/2026 |
| 0.4.0-alpha.4 | 85 | 9/26/2026 |
| 0.4.0-alpha.3 | 103 | 8/19/2026 |
| 0.4.0-alpha.2 | 95 | 8/7/2026 |
| 0.4.0-alpha.1 | 80 | 7/25/2026 |