refactor(policy-engine)!: retarget onto the published agent-control-spec crate - #3939
Merged
MohammadHaroonAbuomar merged 30 commits intoSep 13, 2026
Merged
Conversation
…rol-spec The engine under policy-engine/core was extracted upstream and published as the agent-control-spec crate. Depend on the registry build at an exact pin rather than carrying a fork, and keep policy-engine/core as a deprecation shim over it for one release cycle. Rust ignores #[deprecated] on a pub use re-export (rust-lang/rust#30827), so the shim declares deprecated type aliases and wrapper functions, which do warn at the call site. Four AGT-only modules stay because the published crate does not carry them: artifact validation, the manifest overlay subset, the telemetry sink helpers, and identity. BREAKING CHANGE: the five verdict decisions collapse to the three the agent-hooks contract defines. warn is allow with a warnings[] entry, and escalate is a deny carrying an approval block. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The engine returns a verdict and never mutates the context, so applying a transform, honouring evaluate_only, resolving an approval and deriving the identity trio all become host work. HostEvaluation discharges them and keeps the fields callers already read. A transform is rejected at agent_startup and agent_shutdown, where the contract does not permit one, and is validated in both modes but applied only under Enforce, so an evaluate_only run reports what would happen without acting on it. An escalation is a liftable deny rather than a decision of its own. A deny that reaches enforcement with no resolver configured fails closed as host_error:approval_unresolved instead of passing for an ordinary policy refusal, and a transform failure the host detects carries a host_error rather than borrowing the engine's namespace. Installing the bundled annotator dispatcher moves behind the off-by-default bundled-dispatchers feature. It resolves api_key_env against the host environment, and the provenance gate that withheld those credentials from a network sourced manifest did not survive extraction. Filed upstream as agent-control-spec#20. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
Both are pyo3 and napi bindings over the Rust core rather than consumers of the published packages, so they retarget with it. They now build on HostEvaluation, which keeps the result shape callers already parse. The decision passes through unchanged. Mapping an allow with warnings back to warn, and a liftable deny back to escalate, would emit retired wire values from a three verdict engine and drop both members on the floor, so warnings and approval are carried on the public verdict instead. Warn and Escalate stay declared for import compatibility, documented as values the engine never produces, and Warn keeps permitting: it means allow with a recorded warning, so treating it as a block would turn a retained verdict into a refusal. Manifest::from_url and Runtime::policy_labels are gone upstream and are rebuilt over the public surface; filed as agent-control-spec#23. Host synthesized failures move to the reserved host_error namespace, and both telemetry classifiers learn it so a host failure is no longer unclassified. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The published NuGet package exposes only AcsInterceptor, with no evaluate and no validation surface, so AGT's AgentControl cannot be rebuilt on it; that gap is agent-control-spec#14. .NET therefore keeps reaching the engine through a C ABI. The ABI lives in sdk/rust rather than the core shim. It discharges the host obligations through HostEvaluation before crossing the boundary, so the managed side receives a verdict whose transform is already applied and whose identities are already derived. A core that depended on the SDK could not be packaged either, since the SDK version it would pin is on no registry. A manifest declaring no annotators now builds without opting into the bundled dispatcher, matching the fallback the Rust host already had. Without it a caller with no annotators at all was pushed onto the credential reading path. The managed side carries the three verdict contract: Verdict gained Warnings and Approval, and enforcement routes on a deny that holds an approval block. Warn and Escalate stay declared and keep their documented meanings, so a caller still holding one gets the behaviour it expects rather than a refusal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
Two manifest changes have no compatibility path. The engine accepts exactly one value for agent_control_specification_version and rejects every other at parse time, and the path root $policy_target is now $target with no alias in the manifest grammar. Every manifest moves, including those embedded in test and example sources. The two layers do differ: agent-hooks still accepts $policy_target on a transform path, but the manifest grammar does not. Everything that reads a verdict moves off the retired decisions and recognises an escalation as a deny carrying an approval block. agentmesh and the coding agent example each live in their own cargo workspace, so neither is reached by a workspace test run from policy-engine and both had gone stale against the new API. Two examples leaked. The research policy ordered its size warning ahead of redaction, so a large result carrying a secret took the warn branch and reached the caller unchanged, and it redacted only the first match. The coding policy replaced the whole target object with a bare string, which made its assertion pass on a missing field rather than a redacted one. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The generator writes manifests, so it moves to the single accepted version and the $target path root like everything else. The wire result schema was wrong in both directions. It still allowed warn and escalate, and because it sets additionalProperties: false while omitting warnings and approval it rejected verdicts the engine actually produces: an allow carrying warnings and a liftable deny both failed validation. A transform whose value is null was rejected too, since serde drops a null value and the schema required the member, and the deprecated $policy_target transform root was rejected despite agent-hooks still parsing it. The policy output schemas keep the five names on purpose. warn and escalate remain valid policy language intents that the engine normalizes; only the normalized verdict is constrained to three, and only there may approval ride along, and only on a deny. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
core/tests/conformance_corpus.rs executed the 25 shared conformance cases, which are the cross SDK contract. It was deleted with the rest of the engine and nothing noticed, because no workflow runs the conformance runners: the cases had drifted to a five decision grammar without a single gate going red. Restored in the SDK rather than the core shim, since applying a transform and deriving identities are host obligations now and the expected results are only observable through HostEvaluation. It picks up warnings[] and approval so a normalized verdict is fully pinned, and it runs under the existing cargo test --workspace step rather than needing a new job. Verified discriminating: restoring the pre retarget expectation on the normalizes-warn case turns it red. artifact_enforcement_probe.py drives enforcement cases through the shipped .so by dlopen, avoiding every Rust and .NET harness, so what it tests is the artifact that ships. It is what found the missing no-annotator fallback in the C ABI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
reserved-reasons.json now carries two namespaces with their real producers. runtime_error comes from the engine; host_error is host only and an interceptor must never emit one. Approval and streaming failures were listed as engine errors while the host is what synthesizes them, and adapter_unsupported was renamed in code without being carried over at all. The specification's verdict set, host obligations, approval path and reason tables move to the implemented contract. Sections beyond those still describe the runtime as applying transforms, which is recorded rather than papered over. acs-retarget.md separates gaps only agent-control-spec can close, each linked to its filed issue, from work this repository still owes. It also corrects an earlier claim of ours that the bundled OPA dispatcher reads no credentials: Rego reads the inherited environment through opa.runtime().env, which predates this change but is not what we wrote. The dependency audit records the lockfile movement, which is net negative in agent-governance-rust and close to flat in policy-engine. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
agent-control-spec and agent-hooks-sdk are published on crates.io, verified against the registry API at 0.4.0-alpha.1 and 0.1.0-alpha.4, so the dependency confusion scan should recognise them rather than flag them as possible takeover targets. Adds the terms this change introduces to the repository spell-check list, keeping the file's C-locale ordering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
Four items were recorded as open when nothing upstream was blocking them. manifest_from_url refuses loopback and link-local destinations again. The guard is ported from the pre-retarget engine, including the IPv4-mapped canonicalization that stops [::ffff:169.254.169.254] routing past it. RFC1918 stays allowed so internal policy hosting keeps working. Only literal addresses are checked, which matches the coverage the old engine had. A transform the host applies is revalidated against Limits. The engine checked the snapshot before the transform existed, so growing the target past max_snapshot_bytes would otherwise leave the host carrying a value the engine would have refused. The AgentDojo benchmark policy computes its own redacted value and returns a single transform, replacing every matched span rather than handing the engine an effects list it no longer accepts. SPECIFICATION.md now describes the host as the party that applies a transform, throughout rather than only in the sections retargeted earlier. The packages carrying the three-verdict break move to 0.4.0-beta.0, matching sdk/rust. The Node CI job asserts the packed tarball name, so the generated workflow moves with them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The npm package pins its per-platform native packages through optionalDependencies, and the supply-chain audit resolves those against the live registry. Moving them to a version that does not exist yet fails the gate, so the npm bump belongs to the release rather than to this change. The Rust crates carrying the break keep 0.4.0-beta.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The annotators, mcp, openai and rig integration crates are all publish = false, so cargo never rewrites their path dependency on the Rust SDK into a registry dependency and the version requirement never applies. Carrying one made the cooling-off scanner resolve 0.4.0-beta.0 against crates.io, where it 404s because the crate is not published yet. The examples app already declares the same dependency by path alone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The cooling-off scanner silently dropped any Cargo dependency pinned with the explicit exact-pin operator: `=0.4.0-alpha.1` fails SAFE_VERSION_RE (which requires a leading alphanumeric), so _resolve_cargo_deps skipped the dep instead of checking it. The two crates this PR retargets onto — agent-control-spec 0.4.0-alpha.1 and agent-hooks-sdk 0.1.0-alpha.4 — are both `=`-pinned and therefore escaped the 7-day cooling-off rule entirely. Strip a single leading `=` (with optional following whitespace) from Cargo requirement strings before the safe-version check so exact pins are resolved and age-checked like bare pins. `==` is not valid Cargo syntax and still fails the safe-version check after one strip. Tests cover the string, spaced, and inline-table `=` forms, the invalid `==`/bare-`=` forms, candidate collection, and an end-to-end run in which a too-young `=`-pinned crate fails the check. Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
…nforces Age-checking `=`-pinned cargo dependencies surfaced four problems that the previous scanner silently skipped. serde_yaml was pinned to =0.9.34, which 404s on crates.io because the release carries build metadata and is published as 0.9.34+deprecated. Cargo resolved it anyway, since it ignores build metadata when matching, so the wrong pin was invisible until the registry lookup ran. agent-hooks-sdk drops to =0.1.0-alpha.3. agent-control-spec requires only ^0.1.0-alpha.3, and 0.1.0-alpha.4 was published two days ago, inside the cooling-off window. The alpha.3 release is fourteen days old, so it satisfies both the dependency and the rule, and the workspace's 108 tests pass against it. The node and python binding crates are publish = false, so cargo never rewrites their path dependencies into registry dependencies and the version requirements never applied. Dropping them stops the scanner resolving versions that exist only in this tree. core returns to 0.3.1-beta.0. The Rust SDK is published, so its path dependency on core must name a version, and that version has to exist on crates.io. Like the npm packages, core moves at release time rather than here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The spell-check gate rejects "newcrate". "new-crate" is an equally valid cargo name and reads as two dictionary words. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
The Scanner trip-wire rejects a PR that changes supply-chain scanner code and dependency manifests together, and asks for the scanner update to land first. The change is now #3564, with authorship intact. Every manifest problem it surfaced stays fixed here: the serde_yaml build metadata pin, the agent-hooks-sdk cooling-off window, the meaningless version requirements on path dependencies, and the core version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
…ish precondition Adds the BREAKING_CHANGES.md entry the retarget needs, which was missing. Corrects an overclaim about manifest_from_url. The restored guard covers the URL a caller passes and nothing deeper. A nested extends URL inside a fetched manifest resolves through the loader in agent-control-spec, and the guard resolves the host once rather than revalidating after DNS or a redirect. Records the crates.io publishing posture of agent-control-spec as a merge precondition, filed upstream as responsibleai/agent-control-spec#24. Refreshes the coding_agent example lockfile, which still pinned agent-hooks-sdk 0.1.0-alpha.4 and core 0.3.2-beta.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
…s-registry Signed-off-by: Liam Crumm <liamcrumm@microsoft.com> # Conflicts: # policy-engine/sdk/python/examples/real_packages/foundry_agents.py
The merge with main brought in a committed example manifest still declaring 0.3.1-beta, which the retarget rejects at parse time. Nothing went red, because the manifests in this tree are examples and reference bundles that no test loads, so the failure would have surfaced for a user instead. Sweeps every YAML declaring agent_control_specification_version and runs the overlay validator over it. Overlay is the right depth. It enforces the version and the whole grammar while accepting a fragment that only completes after extends resolution, so bases and whole manifests share one check. Also records why serde_yaml carries build metadata in its version requirement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 51d4e9b7-74f6-46f8-8b55-01be8d5eee05 Signed-off-by: Liam Crumm <liamcrumm@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Validate complete transformed snapshots across native bindings, standardize unresolved .NET approvals, repair native release assets, and require the versioned Python SDK throughout the dependency chain. Keep upstream ownership and remaining coordinated registry releases explicit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Install local policy dependencies before integration, container and fuzz consumers; migrate manifests added on main; order ESRP PyPI publication and reject unsafe bulk GitHub uploads while retaining bulk dry-runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Keep TLS restrictions, checksum verification and failure propagation while avoiding an unsupported retry option in the older fuzz image. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Use a dated nightly toolchain for OSS-Fuzz's sanitizer flags, retain its Cargo coverage wrapper, and specify the native target so host proc macros are not instrumented. Verified the native wheel build with actual sanitizer flags in the pinned fuzz image. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Upgrade agent-control-spec to alpha.3 and agent-hooks-sdk to alpha.5 across all consumers. Preserve explicit OPA compatibility under Cargo feature unification, reuse public manifest/runtime APIs, and retain only behaviorally necessary compatibility surfaces. Verify registry provenance and aged HTTP dependencies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Keep the legacy array-typed version constant derived from upstream with a cardinality guard. Explicitly enable the lightweight OPA feature where alpha.3 otherwise fails to compile, and test the core shim and telemetry crate independently. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Use the aged, hash-verified typing-extensions 4.16.0 release and test the sentinel API required by current AnyIO, avoiding the shared test lock's incompatible downgrade. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Keep generator tests independent of application dependencies while exercising the exact AnyIO import that failed in the agent-os matrix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4f040a65-a9b0-48a0-9ed3-c1384fbe0f00 Signed-off-by: Liam Crumm <liamcrumm@gmail.com>
Carries Liam's policy-engine retarget onto the published agent-control-spec crate unchanged, rebased onto today's main. Conflicts resolved: - agent-governance-python/requirements/ci-test.txt: keep main's typing-extensions 4.16.0 block (same pin and hash as the branch; main carries the explanatory comment from #3928). - policy-engine/core/tests/opa.rs: the branch deletes the core test suite; main's one-line timeout tweak (#3848) targets that deleted file, so the deletion stands. Co-authored-by: Liam Crumm <liamcrumm@gmail.com> Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
Dependency ReviewThe following issues were found:
|
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
📦 Dependency diff (SBOM)Comparing main → mhabuomar/policy-engine-retarget-acs. Summary: ➕ 5 added · ➖ 19 removed · 🔄 10 bumped ➕ Added
|
| Package | Version |
|---|---|
| agent-control-spec | 0.4.0-alpha.3 |
| agent-hooks-sdk | 0.1.0-alpha.5 |
| ryu-js | 1.0.3 |
| ureq-proto | 0.6.1 |
| utf8-zero | 0.8.1 |
➖ Removed
cargo (19)
| Package | Version |
|---|---|
| anes | 0.1.6 |
| cast | 0.3.0 |
| ciborium | 0.2.2 |
| ciborium-io | 0.2.2 |
| ciborium-ll | 0.2.2 |
| criterion | 0.7.0 |
| criterion-plot | 0.6.0 |
| crossbeam-deque | 0.8.6 |
| crossbeam-epoch | 0.9.18 |
| crossbeam-utils | 0.8.21 |
| crunchy | 0.2.4 |
| half | 2.7.1 |
| oorandom | 11.1.5 |
| plotters | 0.3.7 |
| plotters-backend | 0.3.7 |
| plotters-svg | 0.3.7 |
| rayon | 1.12.0 |
| rayon-core | 1.13.0 |
| tinytemplate | 1.2.1 |
🔄 Bumped
cargo (3)
| Package | From | To |
|---|---|---|
| napi-build | 2.3.2 | 2.4.0 |
| portable-atomic | 1.13.1 | 1.14.0 |
| unicode-segmentation | 1.13.2 | 1.13.3 |
other (7)
| Package | From | To |
|---|---|---|
| agent-control-specification-node | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_annotators | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_mcp | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_openai | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_otel | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_py | 0.3.1-beta.0 | 0.4.0-beta.0 |
| agent_control_specification_rig | 0.3.1-beta.0 | 0.4.0-beta.0 |
47 tasks
MohammadHaroonAbuomar
deleted the
mhabuomar/policy-engine-retarget-acs
branch
September 13, 2026 21:30
This was referenced Sep 13, 2026
Closed
Karim Mehalebi (karimad)
pushed a commit
to karimad/agent-governance-toolkit
that referenced
this pull request
Sep 14, 2026
…pec crate (microsoft#3939) Supersedes microsoft#3561. Carries liamcrumm's branch unchanged onto main; two conflict resolutions described in the PR. Co-authored-by: Liam Crumm <liamcrumm@gmail.com> Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
Imran Siddique (imran-siddique)
added a commit
that referenced
this pull request
Sep 14, 2026
The openshell skill's test fixture manifest declared `agent_control_specification_version: 0.3.0-alpha-agt`. After #3939 retargeted the policy engine onto the published agent-control-spec crate, the runtime refuses it: RuntimeError: runtime_error:manifest_invalid: unsupported agent_control_specification_version '0.3.0-alpha-agt'; supported versions are 0.4.0-alpha.1 This surfaced when main was merged into this branch, which had been 85 commits behind and so had not seen the retarget. Only the version string changes. `extends` and `tools`, which this fixture also uses, remain valid blocks in 0.4.0-alpha.1 per policy-engine/README.md's schema table, so #3940's fail-closed on removed manifest fields does not reach them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QRxFm1Z1kE9iraPspwr7j Signed-off-by: Imran Siddique <imran.siddique@opaque.co>
19 tasks
Ayobami Omotayo (dannyyol)
added a commit
to dannyyol/agent-governance-toolkit
that referenced
this pull request
Sep 15, 2026
Align uk-regulatory YAML packs with the SDK version accepted after microsoft#3939 so AgentControl.from_path and policy validation can load them.
Ayobami Omotayo (dannyyol)
added a commit
to dannyyol/agent-governance-toolkit
that referenced
this pull request
Sep 15, 2026
Align uk-regulatory YAML packs with the SDK version accepted after microsoft#3939 so AgentControl.from_path and policy validation can load them. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com>
MohammadHaroonAbuomar
added a commit
that referenced
this pull request
Sep 15, 2026
…#3254) * feat(examples): add UK regulatory policy pack (UK GDPR, ICO ADM, FCA) Add governance starter policies for GB jurisdiction covering UK GDPR/DPA 2018, DUAA 2025 automated decision-making safeguards, and FCA principles-based financial conduct, with OPA Rego references and jurisdiction router wiring. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * test(examples): add OPA tests for UK regulatory policy pack Add 38 Rego unit tests covering UK GDPR, ICO ADM, FCA conduct, and GB jurisdiction routing, plus a run_tests.sh runner and README instructions. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * docs(examples): restore policies README and add UK pack entry Keep upstream README structure (Using this directory, Policy format, Related) and add a Policy Packs table row for uk-regulatory without replacing existing documentation. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * docs(examples): drop README changes covered by separate PR Restore examples/policies/README.md to match upstream main; policy pack catalog updates are handled elsewhere. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(examples): restore India routing alongside UK in jurisdiction router Add GB pack mappings without removing upstream IN entries (dpdp, certin, rbi, sebi, aadhaar). Add regression test to keep India routing intact. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(examples): align UK policies with DUAA regulatory review Refine breach-notification messaging, escalate cross-border transfers instead of blanket blocking, correct Art. 22B special-category ADM requirements, and sync YAML with Rego reference implementations. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * Addressed review feedback: replaced all 7 escalate YAML actions with block, corrected PRIN 2A.4 and Art. 33 citations, removed DPA s.67 from general processing scope, removed AU from adequacy list, dropped unused Rego schema field. Validated all 3 YAMLs and 41/41 OPA tests pass Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * chore(spell): add UK policy terms for cspell check Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(docs): remove v4 PolicyDocument snippet from UK regulatory README Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * refactor(examples): migrate UK regulatory pack to native ACS manifests Convert the YAML packs to ACS manifests, add the shared ACS result adapter, harden UK GDPR transfer checks (platform-set adequacy/DPF only), and stringify non-string output before regex evaluation. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * chore(examples): add MIT license header to UK Rego test runner Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * chore(spell): move UK regulatory terms section header with other cspell groups Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(examples): detect HMRC-spaced UK National Insurance numbers Match compact and spaced NI formats plus "No." phrasing, add regression tests, and allowlist the UK regulatory terms cspell flagged. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(policies): catch NHS and NI numbers in common UK output phrasings Deny full National Insurance / National Health Service wording and spaced official ID formats so these PII rules no longer fail open Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(policies): close UK pack deny fail-opens and caller trust bypasses Harden NHS/NI separators, match Do not with don't, accept ASCII hyphens in ICO contest phrasing, and require platform-set FCA trading approval. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * chore: remove local spell-check diff output Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(examples): bump UK ACS manifests to 0.4.0-alpha.1 Align uk-regulatory YAML packs with the SDK version accepted after #3939 so AgentControl.from_path and policy validation can load them. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * docs(examples): fix UK GDPR template path after package layout move Point UK pack docs and Rego comments at agent-governance-python/agent-os/templates/policies/gdpr.yaml. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * fix(policies): align UK GDPR adequacy defaults with ICO full-adequacy ISO codes Replace region tokens and partial-adequacy countries in the default set with ICO full-adequacy ISO-3166 codes, keep CA/JP/US out of defaults, and cover EU allow plus CA/JP deny paths in Rego tests. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * docs(examples): fix UK pack README ACS snippet and cspell terms Use evaluate_intervention_point instead of the nonexistent AgentControl.evaluate, and allowlist APPI, PIHBOs, and PIPEDA for spell-check. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> * docs(examples): clarify UK pack README ACS and OPA usage Document warn (from audit) ACS mapping, fix opa eval to use an input file, note from_path pack-only vs router two-layer selection, and use a repo-root YAML path in the AgentControl example. Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> --------- Signed-off-by: Ayo Omotayo <ayonifeoluwa@gmail.com> Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
18 tasks
Karim Mehalebi (karimad)
added a commit
to karimad/agent-governance-toolkit
that referenced
this pull request
Sep 17, 2026
Review caught that agent_os (force-included into this same wheel) imports agent_control_specification directly in 4 places: providers.py, cmd_validate.py, _native_adapter_runtime.py, and openai_agents_sdk.py. That package previously arrived only transitively via agt-policies's own pin, which the prior commit removed from the base dependency set - trading the original unresolvable-install failure for a quieter ImportError at runtime the moment agent_os actually exercised one of those paths. Fix: declare agent-control-specification>=0.3.1b0,<0.4.0 directly in agent-governance-toolkit-core's own dependencies, matching the range agt-policies 5.0.0 already resolved to before microsoft#3939. Verified in a clean venv: all four previously-broken agent_os modules import cleanly, and cmd_validate.py's _validate_manifest() actually runs end-to-end (not just import-checked). govern()'s contains/startswith/endswith path (microsoft#3924) still passes both the deny and allow cases. One related, pre-existing gap surfaced during this verification and is NOT fixed here (out of scope for a packaging PR): _native_adapter_runtime .py's _session_for() imports HostSession from agent_control_specification, which genuinely does not exist in any published release yet (checked 0.3.1b1's exports directly). That call path was already broken before this PR - it depends on ACS 0.4.0b0's API regardless of how the agt-policies/agent-control-specification pins are arranged - so it's unaffected by this change either way. Also: moved the new 'migrate' extra out from under the '--- Bundles ---' header (it's a single-package extra like redis/django, not a bundle), and added a CHANGELOG.md [Unreleased]/Fixed entry. Signed-off-by: karimad <kmehaleb@gmail.com>
Karim Mehalebi (karimad)
added a commit
to karimad/agent-governance-toolkit
that referenced
this pull request
Sep 17, 2026
Review caught that agent_os (force-included into this same wheel) imports agent_control_specification directly in 4 places: providers.py, cmd_validate.py, _native_adapter_runtime.py, and openai_agents_sdk.py. That package previously arrived only transitively via agt-policies's own pin, which the prior commit removed from the base dependency set - trading the original unresolvable-install failure for a quieter ImportError at runtime the moment agent_os actually exercised one of those paths. Fix: declare agent-control-specification>=0.3.1b0,<0.4.0 directly in agent-governance-toolkit-core's own dependencies, matching the range agt-policies 5.0.0 already resolved to before microsoft#3939. Verified in a clean venv: all four previously-broken agent_os modules import cleanly, and cmd_validate.py's _validate_manifest() actually runs end-to-end (not just import-checked). govern()'s contains/startswith/endswith path (microsoft#3924) still passes both the deny and allow cases. One related, pre-existing gap surfaced during this verification and is NOT fixed here (out of scope for a packaging PR): _native_adapter_runtime .py's _session_for() imports HostSession from agent_control_specification, which genuinely does not exist in any published release yet (checked 0.3.1b1's exports directly). That call path was already broken before this PR - it depends on ACS 0.4.0b0's API regardless of how the agt-policies/agent-control-specification pins are arranged - so it's unaffected by this change either way. Also: moved the new 'migrate' extra out from under the '--- Bundles ---' header (it's a single-package extra like redis/django, not a bundle), and added a CHANGELOG.md [Unreleased]/Fixed entry. Signed-off-by: karimad <kmehaleb@gmail.com>
MohammadHaroonAbuomar
pushed a commit
that referenced
this pull request
Sep 17, 2026
… installs (#4017) * fix(core): move agt-policies to an opt-in extra, not a base dependency agent-governance-toolkit-core's dependencies pin agt-policies>=5.1.0,<6.0, which in turn pins agent-control-specification>=0.4.0b0,<0.5.0. Neither version is published to PyPI (PyPI tops out at agt-policies 5.0.0 and agent-control-specification 0.3.1b1), so a plain 'pip install agent-governance-toolkit-core' or '[full]' cannot resolve. agt-policies backs only the v4-to-ACS manifest migration CLI ('agt migrate'). Nothing in agentmesh.governance (govern(), GovernanceDenied, policy.py/PolicyEngine) imports agt or agent_control_specification - confirmed by grepping agent-mesh/src/agentmesh/ for both. The base governance runtime does not need this dependency at all. Moves it to a new 'migrate' extra instead, matching the existing optional-dependencies pattern for other CLI/framework-specific pieces (mcp, redis, django, etc.). Verified: a clean venv can now 'pip install agent-governance-toolkit-core[full]' and exercise govern()'s contains/startswith/endswith operators (#3924) end-to-end without agt-policies or agent-control-specification installed at all. Signed-off-by: karimad <kmehaleb@gmail.com> * trim comment on the migrate extra Signed-off-by: karimad <kmehaleb@gmail.com> * fix(core): give agent-control-specification its own base dependency Review caught that agent_os (force-included into this same wheel) imports agent_control_specification directly in 4 places: providers.py, cmd_validate.py, _native_adapter_runtime.py, and openai_agents_sdk.py. That package previously arrived only transitively via agt-policies's own pin, which the prior commit removed from the base dependency set - trading the original unresolvable-install failure for a quieter ImportError at runtime the moment agent_os actually exercised one of those paths. Fix: declare agent-control-specification>=0.3.1b0,<0.4.0 directly in agent-governance-toolkit-core's own dependencies, matching the range agt-policies 5.0.0 already resolved to before #3939. Verified in a clean venv: all four previously-broken agent_os modules import cleanly, and cmd_validate.py's _validate_manifest() actually runs end-to-end (not just import-checked). govern()'s contains/startswith/endswith path (#3924) still passes both the deny and allow cases. One related, pre-existing gap surfaced during this verification and is NOT fixed here (out of scope for a packaging PR): _native_adapter_runtime .py's _session_for() imports HostSession from agent_control_specification, which genuinely does not exist in any published release yet (checked 0.3.1b1's exports directly). That call path was already broken before this PR - it depends on ACS 0.4.0b0's API regardless of how the agt-policies/agent-control-specification pins are arranged - so it's unaffected by this change either way. Also: moved the new 'migrate' extra out from under the '--- Bundles ---' header (it's a single-package extra like redis/django, not a bundle), and added a CHANGELOG.md [Unreleased]/Fixed entry. Signed-off-by: karimad <kmehaleb@gmail.com> * shorten comments Signed-off-by: karimad <kmehaleb@gmail.com> * docs: disclose still-unresolvable migrate-extra pin, file tracking issue The migrate extra's agt-policies>=5.1.0,<6.0 pin predates this PR and is unchanged by it. It's still unresolvable on its own today (agt-policies 5.1.0 isn't published), and will conflict with this PR's new base ACS pin once it is (agt-policies would then require ACS>=0.4.0b0, base requires <0.4.0). Documented in the CHANGELOG and the extra itself, tracked in #4019 so it isn't rediscovered fresh. Signed-off-by: Karim Mehalebi <kmehalebi@egencia.com> * docs: tell agt migrate users they now need the migrate extra Signed-off-by: Karim Mehalebi <kmehalebi@egencia.com> * fix(core): pin agent-control-specification to 0.4.0b0 range agent_os requires Reviewer found 0.3.1b1 lacks HostSession and rejects every in-repo manifest, breaking the adapter runtime and agent-os validate despite the install itself resolving. Update the base pin and changelog entry to match. Signed-off-by: Karim Mehalebi <kmehaleb@gmail.com> --------- Signed-off-by: karimad <kmehaleb@gmail.com> Signed-off-by: Karim Mehalebi <kmehalebi@egencia.com> Signed-off-by: Karim Mehalebi <kmehaleb@gmail.com> Co-authored-by: Karim Mehalebi <kmehalebi@egencia.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.
Related Issue
Supersedes #3561 (liamcrumm). This PR carries Liam's branch unchanged, merged onto today's main with two conflict resolutions, so it can land while he is away. Authorship is his; see the Co-authored-by trailer and the original PR for the review history.
Problem & Solution
Conflict resolutions in the merge commit:
agent-governance-python/requirements/ci-test.txt: kept main's typing-extensions 4.16.0 block (same pin and hash as the branch; main has the explanatory comment from ci: bump typing-extensions test pin to 4.16.0 #3928).policy-engine/core/tests/opa.rs: the branch deletes the core test suite; main's one-line timeout tweak (test: stabilize OPA timeout regression #3848) targets that deleted file, so the deletion stands.Everything below is Liam's original description.
Summary
Replace AGT's embedded policy decision engine with
agent-control-spec =0.4.0-alpha.3andagent-hooks-sdk =0.1.0-alpha.5, the latest published pair verified September 8, while retaining AGT's existing host SDKs and native bindings. This is a breaking engine/host migration, not the six-package restructure.Problem
AGT maintains a second implementation of an extracted engine. ACS now returns a three-decision verdict; AGT must apply transforms, handle enforcement mode and approvals, and retain its legacy host result shape.
The September 8 reassessment also found release and compatibility defects in this branch. The latest commits merge current main, repair those defects, and distinguish pinned-engine limitations from functionality added in later ACS releases.
Changes
policy-engine/coreagent-control-spec =0.4.0-alpha.3. Derive the legacy array-typed constant from the public supported-version list with a cardinality guard; retain behaviorally necessary bounded validation, telemetry and identity helpers.host_error:approval_unresolved; version all five packages at0.4.0-beta.0.0.4.0b0; require it from the generator andagt-policies5.1.0. The consolidated core requiresagt-policies>=5.1.0,<6.0.0.4.0-alpha.1, manifest root$policy_targetto$target, and five-decision assumptions to the three-decision contract.All four direct ACS dependencies and all three consumer lockfiles use the updated registry pair. The crate checksum matches the registry and its trusted-publishing record. HTTP dependencies remain on aged
ureq3.4.0 /ureq-proto0.6.1 rather than their September 6 successors.Compatibility and rollout
warnbecomesallowwithwarnings[];escalatebecomes a liftabledenywithapproval.$policy_targetas an alias. The transform-path parser is a separate contract.0.4.0-alpha.1; manifests must not be bumped to the package version.AcsInterceptor/ActivatedPolicyconsumers follow ACS's feature selection. Enabling Rego elsewhere cannot silently switch the legacy host or C ABI.opafeature while keeping upstream defaults off, and are checked independently so workspace feature unification cannot hide this issue.opa,bundled-dispatchersfeature selection. It requires trusted manifests and transitive configuration. The default Rust SDK and production Python/Node builds do not enable bundled annotators.See
policy-engine/docs/acs-retarget.mdfor the symbol mapping and release order.Outstanding merge condition
The selected alpha.3 artifact has repository metadata and a trusted-publishing record bound to upstream commit
4c47b57033b98c0d2ccf1b94624f058815db0a9c. The review's remaining organization/team co-owner condition is not waived: the registry still lists one individual owner. Upstream responsibleai/agent-control-spec#24 remains open.The cooling-off scanner fix was split into #3564 and merged August 1. Its code is not changed here.
Pinned-engine limitations remain tracked upstream in responsibleai/agent-control-spec#20, #21, #22 and #23. The original binding-validation gap #14 was closed by #15; later releases expose more APIs, so the former blanket claim that bindings only expose
AcsInterceptoris no longer current.Testing
Local validation of the upstream upgrade:
-D warnings.core --no-default-features --libandotel --libchecks pass. The compatibility test also compiles the legacy supported-version constant as[&str; 1].pip checkand generates a valid manifest.Both independent reviewers confirmed their findings resolved with no new actionable issues at
aa25d0af. The legacy constant type and isolated no-backend builds have regression coverage, and the generated CI checks pass.The previous agent-os CI failure involved AnyIO 4.15.1 and the hashed test pin
typing-extensions==4.15.0; it was also present in the merged main baseline. Commitsf6b69289anded0f9bb3fix that mismatch with 4.16.0 and regression coverage. All three agent-os jobs now pass.Final verification at
ed0f9bb3: 151 checks pass, none fail and none are pending. Five checks are skipped/neutral, including the separate CodeQL comparison warning explained below. The small shared-dependency delta was directly reviewed; the earlier engine upgrade has clean independent reviews. The registry ownership condition is not waived, and the active Protect ruleset still requires a code-owner approval of the latest push. This is not yet a merge-ready verdict.CodeQL comparison warning
The missing default configuration is a separate Microsoft SDL API-upload analysis on main (48 rules, 54 findings), including custom rules not present in the standard Python/JavaScript workflow. It is not an empty duplicate and has not been deleted or replaced with a placeholder report. The current enforced required-status list does not include CodeQL; the existing workflow analyses are working. A matching SDL comparison needs the original publisher/query-pack access. The warning remains documented rather than hidden.
Attribution and AI assistance
Depends on the upstream engine extracted from this repository,
responsibleai/agent-control-spec, and theresponsibleai/agent-hookscontract. Written with GitHub Copilot CLI. No review comments or replies were posted as part of the September 8 maintenance.Type of Change
Package(s) Affected
Testing
Run as an independent review group: Rust workspace tests (
cargo test --locked), the Python packages touched, the repo quality gates, and three adversarial reviewers on the combined diff before merge. Findings that survive go in a separate follow-up PR after this lands.Checklist
Attribution & Prior Art
AI Assistance
IP, Patents, and Licensing