agentgovern 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentgovern-2.3.0 → agentgovern-2.4.0}/CHANGELOG.md +26 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/PKG-INFO +8 -1
- {agentgovern-2.3.0 → agentgovern-2.4.0}/README.md +7 -0
- agentgovern-2.4.0/RELEASING.md +72 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/__init__.py +1 -1
- agentgovern-2.4.0/agentgovern/_version.py +1 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/client.py +8 -1
- {agentgovern-2.3.0 → agentgovern-2.4.0}/pyproject.toml +1 -1
- agentgovern-2.4.0/tests/test_policy_engine_url.py +79 -0
- agentgovern-2.3.0/RELEASING.md +0 -65
- agentgovern-2.3.0/agentgovern/_version.py +0 -1
- {agentgovern-2.3.0 → agentgovern-2.4.0}/.gitignore +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/LICENSE +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/__main__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/exceptions.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/gate2.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/cli.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/data/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/data/hook.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/drift.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/installer.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/hook/settings.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/instrumentors/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/instrumentors/_base.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/instrumentors/langchain.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/instrumentors/langgraph.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentgovern/types.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentshield/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentshield/client.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/agentshield/types.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/examples/langgraph_credit_decision_agent.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/__init__.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/conftest.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_bundled_hook.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_drift.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_context_snapshot.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_dispatch.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_outbox_queue.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_payload_extraction.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_payloads.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_remediation_message.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_timing_log.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_transcript_reading.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_turn_index.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_hook_v2_warn_verdict.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_installer.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_matcher_coverage.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_settings.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/hook/test_tool_map_classification.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_base_instrumentor.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_client.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_evaluate_input.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_gate2_full_path.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_gate2_latency.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_gate2_verdict_handler.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_import_guard.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_instrument_langchain.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_langchain.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_langchain_1x_agent.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_langchain_gate1.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_langchain_gate2_callbacks.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_langgraph.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_output_capture_contract.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_payload_schema.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_rate_limit_handling.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_register_contract.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_timestamp.py +0 -0
- {agentgovern-2.3.0 → agentgovern-2.4.0}/tests/test_version_consistency.py +0 -0
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.4.0 — release date is the `sdk-v2.4.0` tag's (prepared 2026-09-30)
|
|
4
|
+
|
|
5
|
+
### Change — the SDK reaches the policy engine at a stable name, `https://engine.zirahn.com`
|
|
6
|
+
|
|
7
|
+
`evaluate_input()` (Gate 1) and Gate 2's output checks call the policy engine
|
|
8
|
+
directly. **Versions 2.3.0 and earlier call it at
|
|
9
|
+
`https://agentgovern.onrender.com`, a hostname Render issued for one specific
|
|
10
|
+
service.** Render cannot move a service to another region: a new service
|
|
11
|
+
means a new hostname. So an SDK pinned to that name cannot follow the engine
|
|
12
|
+
if it moves.
|
|
13
|
+
|
|
14
|
+
- The default `policy_engine_url` is now **`https://engine.zirahn.com`**. It
|
|
15
|
+
is a custom domain pointing at the same engine today, so **latency and
|
|
16
|
+
behaviour are unchanged**. What changes is that a future move of the engine
|
|
17
|
+
needs no SDK release.
|
|
18
|
+
- **2.3.0 and earlier keep working.** `agentgovern.onrender.com` still
|
|
19
|
+
serves the same engine, and it will not be removed while any supported
|
|
20
|
+
version defaults to it. Upgrading moves you to the stable name:
|
|
21
|
+
`pip install --upgrade agentgovern`.
|
|
22
|
+
- **Overrides are unchanged.** The `policy_engine_url` argument to `init()`,
|
|
23
|
+
then the `AGENTGOVERN_POLICY_ENGINE_URL` environment variable, still take
|
|
24
|
+
precedence over the default. **If you set either yourself, you are not
|
|
25
|
+
affected.**
|
|
26
|
+
- The Claude Code hook is unaffected. It reaches the engine through the
|
|
27
|
+
dashboard's API, not directly.
|
|
28
|
+
|
|
3
29
|
## 2.3.0 — release date is the `sdk-v2.3.0` tag's (prepared 2026-09-29)
|
|
4
30
|
|
|
5
31
|
### Security — the Claude Code hook now sees every tool call, but only after you reinstall it (NAGT-187)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentgovern
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Compliance-as-code middleware for agentic AI workflows.
|
|
5
5
|
Project-URL: Homepage, https://agentgovern.zirahn.com
|
|
6
6
|
Project-URL: Repository, https://github.com/ahmedkhan-zirahn/agentgovern
|
|
@@ -190,8 +190,15 @@ Enable policy packs from the [AgentGovern dashboard](https://agentgovern.zirahn.
|
|
|
190
190
|
| `api_key` | required | SDK ingest key from the dashboard |
|
|
191
191
|
| `base_url` | `https://agentgovern.zirahn.com` | API endpoint |
|
|
192
192
|
| `environment` | `"production"` | `"production"` \| `"staging"` \| `"development"` |
|
|
193
|
+
| `policy_engine_url` | `https://engine.zirahn.com` | Policy engine endpoint for Gate 1 (`evaluate_input`) and Gate 2 checks. Override with this argument or the `AGENTGOVERN_POLICY_ENGINE_URL` env var |
|
|
193
194
|
| `fail_silently` | `True` | If `True`, SDK errors never raise into your agent |
|
|
194
195
|
|
|
196
|
+
**Policy engine address (2.4.0).** The default engine address is now the stable name
|
|
197
|
+
`https://engine.zirahn.com`. Versions 2.3.0 and earlier call `https://agentgovern.onrender.com`
|
|
198
|
+
directly. That address keeps working, so nothing breaks if you stay on an older version, but only
|
|
199
|
+
the stable name can follow the engine if it moves. Upgrade with `pip install --upgrade agentgovern`.
|
|
200
|
+
If you set `policy_engine_url` or `AGENTGOVERN_POLICY_ENGINE_URL` yourself, it still takes precedence.
|
|
201
|
+
|
|
195
202
|
## Claude Code Hook
|
|
196
203
|
|
|
197
204
|
The SDK ships a built-in CLI for installing the AgentGovern hook into Claude Code. The hook
|
|
@@ -147,8 +147,15 @@ Enable policy packs from the [AgentGovern dashboard](https://agentgovern.zirahn.
|
|
|
147
147
|
| `api_key` | required | SDK ingest key from the dashboard |
|
|
148
148
|
| `base_url` | `https://agentgovern.zirahn.com` | API endpoint |
|
|
149
149
|
| `environment` | `"production"` | `"production"` \| `"staging"` \| `"development"` |
|
|
150
|
+
| `policy_engine_url` | `https://engine.zirahn.com` | Policy engine endpoint for Gate 1 (`evaluate_input`) and Gate 2 checks. Override with this argument or the `AGENTGOVERN_POLICY_ENGINE_URL` env var |
|
|
150
151
|
| `fail_silently` | `True` | If `True`, SDK errors never raise into your agent |
|
|
151
152
|
|
|
153
|
+
**Policy engine address (2.4.0).** The default engine address is now the stable name
|
|
154
|
+
`https://engine.zirahn.com`. Versions 2.3.0 and earlier call `https://agentgovern.onrender.com`
|
|
155
|
+
directly. That address keeps working, so nothing breaks if you stay on an older version, but only
|
|
156
|
+
the stable name can follow the engine if it moves. Upgrade with `pip install --upgrade agentgovern`.
|
|
157
|
+
If you set `policy_engine_url` or `AGENTGOVERN_POLICY_ENGINE_URL` yourself, it still takes precedence.
|
|
158
|
+
|
|
152
159
|
## Claude Code Hook
|
|
153
160
|
|
|
154
161
|
The SDK ships a built-in CLI for installing the AgentGovern hook into Claude Code. The hook
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Releasing agentgovern to PyPI
|
|
2
|
+
|
|
3
|
+
Releases are automated via `.github/workflows/publish-sdk.yml` using PyPI trusted publishing (OIDC — no API tokens needed). Pushing a `sdk-v*` tag triggers a build and publish automatically.
|
|
4
|
+
|
|
5
|
+
## Prerequisites (one-time PyPI setup)
|
|
6
|
+
|
|
7
|
+
Before the first automated publish, configure trusted publishing on PyPI:
|
|
8
|
+
|
|
9
|
+
1. Go to https://pypi.org/manage/project/agentgovern/settings/publishing/
|
|
10
|
+
2. Add a new trusted publisher with these exact values:
|
|
11
|
+
|
|
12
|
+
| Field | Value |
|
|
13
|
+
|-------------------|------------------------------|
|
|
14
|
+
| Owner | ZirahnAI |
|
|
15
|
+
| Repository name | agentgovern |
|
|
16
|
+
| Workflow filename | publish-sdk.yml |
|
|
17
|
+
| Environment name | pypi |
|
|
18
|
+
|
|
19
|
+
**Note:** the repository moved from `ahmedkhan-zirahn` to `ZirahnAI` in September 2026. A publisher for the old owner existed and was **deleted on 2026-09-14**. A trusted publisher that names a path the organisation no longer controls is a standing binding to a namespace someone else could later claim. See NAGT-314 in `docs/ROADMAP.md`.
|
|
20
|
+
|
|
21
|
+
3. Save. No API token needed after this.
|
|
22
|
+
|
|
23
|
+
Also create the `pypi` environment in GitHub, and restrict it to release tags:
|
|
24
|
+
- Go to https://github.com/ZirahnAI/agentgovern/settings/environments
|
|
25
|
+
- Create the environment named `pypi`.
|
|
26
|
+
- Under **Deployment branches and tags**, choose **Selected branches and tags** and add a **tag** rule `sdk-v*`. The publish job carries `environment: pypi`, so it can only run from an `sdk-v*` tag.
|
|
27
|
+
- **Required reviewers is not available here.** GitHub offers it for environments in private repositories only on Enterprise, and this repository is private on the Team plan (operator-confirmed 2026-09-30). So the publish does not pause for approval. **Pushing the tag is the release decision.**
|
|
28
|
+
- Optionally, add a repository **tag ruleset** on `refs/tags/sdk-v*` that restricts creation to admins. One named "sdk release tags" exists. It was **not enforced** when checked on 2026-09-30, so it has no effect until its enforcement is set to Active.
|
|
29
|
+
|
|
30
|
+
Check the environment with `gh api repos/ZirahnAI/agentgovern/environments/pypi/deployment-branch-policies`, which should list `{"name": "sdk-v*", "type": "tag"}`.
|
|
31
|
+
|
|
32
|
+
## Release steps
|
|
33
|
+
|
|
34
|
+
1. **Bump the version** in two places:
|
|
35
|
+
```
|
|
36
|
+
packages/sdk-python/agentgovern/_version.py → __version__ = "0.X.Y"
|
|
37
|
+
packages/sdk-python/pyproject.toml → version = "0.X.Y"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. **Add a CHANGELOG entry** (if `CHANGELOG.md` exists) describing what changed.
|
|
41
|
+
|
|
42
|
+
3. **Commit the version bump:**
|
|
43
|
+
```bash
|
|
44
|
+
git add packages/sdk-python/agentgovern/_version.py packages/sdk-python/pyproject.toml
|
|
45
|
+
git commit -m "chore(sdk): bump version to 0.X.Y"
|
|
46
|
+
git push
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
4. **Tag the merged commit and push that one tag.** Never `git push --tags`, which pushes every local tag, and any stray `sdk-v*` among them would publish:
|
|
50
|
+
```bash
|
|
51
|
+
git fetch origin
|
|
52
|
+
git tag sdk-v0.X.Y <merged-commit-sha>
|
|
53
|
+
git push origin sdk-v0.X.Y
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The `publish-sdk.yml` workflow triggers on the tag push. It builds, checks the wheel's declared dependencies, installs that exact wheel in a clean venv, and then publishes to PyPI. **There is no approval step** (see above). PyPI never accepts a version twice, so a mistaken tag uses up that version for good.
|
|
57
|
+
|
|
58
|
+
5. **Verify** at https://pypi.org/project/agentgovern/ — the new version should appear within a few minutes.
|
|
59
|
+
|
|
60
|
+
## Manual fallback (workflow_dispatch)
|
|
61
|
+
|
|
62
|
+
To re-run a publish after a failed run, trigger the workflow manually **from the release tag**:
|
|
63
|
+
|
|
64
|
+
1. Go to https://github.com/ZirahnAI/agentgovern/actions/workflows/publish-sdk.yml
|
|
65
|
+
2. Click **Run workflow**, choose the **tag** `sdk-v0.X.Y` under "Use workflow from", then **Run workflow**.
|
|
66
|
+
|
|
67
|
+
**A run dispatched from `main` (or any branch) cannot publish.** Its build job runs, but the publish job targets the `pypi` environment, which only accepts `sdk-v*` tags. That comes from the environment restriction above, per GitHub's documented behaviour; it has not been tested by dispatching from `main`. The run publishes whatever version `pyproject.toml` says at that ref.
|
|
68
|
+
|
|
69
|
+
## Trusted-publisher history
|
|
70
|
+
|
|
71
|
+
- **2026-09-14:** run `34876650141` (dispatched from `main`) authenticated through the `ZirahnAI/agentgovern` publisher. PyPI then refused to re-upload 2.2.1 (`400 File already exists`), so the run's conclusion was `failure`.
|
|
72
|
+
- **2026-09-30:** 2.3.0 was the first version published end to end from the `ZirahnAI` repository, by run `36667118357` from tag `sdk-v2.3.0`.
|
|
@@ -151,7 +151,7 @@ def init(
|
|
|
151
151
|
base_url: Vercel deployment URL (action ingest + agent registration).
|
|
152
152
|
policy_engine_url: Render policy engine URL (Gate 1 evaluate/input).
|
|
153
153
|
Defaults to ``AGENTGOVERN_POLICY_ENGINE_URL`` env var, then
|
|
154
|
-
``https://
|
|
154
|
+
``https://engine.zirahn.com``.
|
|
155
155
|
fail_silently: If ``True``, SDK errors never raise into your agent,
|
|
156
156
|
after initialisation. It does not affect this function.
|
|
157
157
|
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.4.0"
|
|
@@ -53,6 +53,13 @@ def _iso_timestamp_utc(dt: datetime | None = None) -> str:
|
|
|
53
53
|
return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{dt.microsecond // 1000:03d}Z"
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
# The policy engine's stable name. SDK <= 2.3.0 defaulted to the Render-issued
|
|
57
|
+
# hostname https://agentgovern.onrender.com, which names one Render service and
|
|
58
|
+
# cannot follow the engine to a new one (Render cannot change a service's
|
|
59
|
+
# region: docs/audit-reports/engine-region-move-phase1-2026-09-30.md). A custom
|
|
60
|
+
# domain can be re-pointed, so a future engine move needs no SDK release.
|
|
61
|
+
DEFAULT_POLICY_ENGINE_URL = "https://engine.zirahn.com"
|
|
62
|
+
|
|
56
63
|
_FLUSH_INTERVAL = 1.0 # seconds between automatic flushes
|
|
57
64
|
_BATCH_SIZE = 100 # flush early when buffer hits this
|
|
58
65
|
_BUFFER_MAXLEN = 10_000 # drop oldest when full
|
|
@@ -107,7 +114,7 @@ class AgentGovernClient:
|
|
|
107
114
|
self.policy_engine_url = (
|
|
108
115
|
policy_engine_url
|
|
109
116
|
or os.environ.get("AGENTGOVERN_POLICY_ENGINE_URL")
|
|
110
|
-
or
|
|
117
|
+
or DEFAULT_POLICY_ENGINE_URL
|
|
111
118
|
).rstrip("/")
|
|
112
119
|
self.fail_silently = fail_silently
|
|
113
120
|
self.batch_size = batch_size
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""How the SDK resolves the policy engine URL (2.4.0: default moved to engine.zirahn.com).
|
|
2
|
+
|
|
3
|
+
Precedence is unchanged: the ``policy_engine_url`` argument, then the
|
|
4
|
+
``AGENTGOVERN_POLICY_ENGINE_URL`` env var, then the default. No network call is
|
|
5
|
+
made: nothing is queued, and flush_interval=999 keeps the periodic flush asleep.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Iterator
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
import agentgovern
|
|
15
|
+
from agentgovern import client as client_mod
|
|
16
|
+
from agentgovern.client import DEFAULT_POLICY_ENGINE_URL, AgentGovernClient
|
|
17
|
+
|
|
18
|
+
ENV = "AGENTGOVERN_POLICY_ENGINE_URL"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def make_client() -> Iterator:
|
|
23
|
+
made: list[AgentGovernClient] = []
|
|
24
|
+
|
|
25
|
+
def _make(**kwargs) -> AgentGovernClient:
|
|
26
|
+
c = AgentGovernClient(
|
|
27
|
+
api_key="ag_test_key",
|
|
28
|
+
environment="development",
|
|
29
|
+
base_url="http://localhost:3000",
|
|
30
|
+
flush_interval=999,
|
|
31
|
+
**kwargs,
|
|
32
|
+
)
|
|
33
|
+
made.append(c)
|
|
34
|
+
return c
|
|
35
|
+
|
|
36
|
+
yield _make
|
|
37
|
+
for c in made:
|
|
38
|
+
c.shutdown(timeout=2.0)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_default_is_the_stable_custom_domain(make_client, monkeypatch) -> None:
|
|
42
|
+
monkeypatch.delenv(ENV, raising=False)
|
|
43
|
+
assert make_client().policy_engine_url == "https://engine.zirahn.com"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_default_is_no_longer_the_render_hostname(make_client, monkeypatch) -> None:
|
|
47
|
+
monkeypatch.delenv(ENV, raising=False)
|
|
48
|
+
assert "onrender.com" not in make_client().policy_engine_url
|
|
49
|
+
assert "onrender.com" not in DEFAULT_POLICY_ENGINE_URL
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_env_var_overrides_the_default(make_client, monkeypatch) -> None:
|
|
53
|
+
monkeypatch.setenv(ENV, "https://engine.example.test/")
|
|
54
|
+
assert make_client().policy_engine_url == "https://engine.example.test"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_argument_overrides_env_and_default(make_client, monkeypatch) -> None:
|
|
58
|
+
monkeypatch.setenv(ENV, "https://from-env.example.test")
|
|
59
|
+
c = make_client(policy_engine_url="https://from-arg.example.test")
|
|
60
|
+
assert c.policy_engine_url == "https://from-arg.example.test"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_old_host_still_selectable_explicitly(make_client, monkeypatch) -> None:
|
|
64
|
+
# Pinning the pre-2.4.0 host keeps working: the override path is unchanged.
|
|
65
|
+
monkeypatch.delenv(ENV, raising=False)
|
|
66
|
+
c = make_client(policy_engine_url="https://agentgovern.onrender.com")
|
|
67
|
+
assert c.policy_engine_url == "https://agentgovern.onrender.com"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_init_docstring_names_the_actual_default() -> None:
|
|
71
|
+
# Derived from the constant, so the docstring cannot drift from the code.
|
|
72
|
+
assert DEFAULT_POLICY_ENGINE_URL in (agentgovern.init.__doc__ or "")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_no_other_default_literal_in_client_source() -> None:
|
|
76
|
+
# The constant is the single source: no second hard-coded engine host.
|
|
77
|
+
src = open(client_mod.__file__, encoding="utf-8").read()
|
|
78
|
+
assert src.count(f'"{DEFAULT_POLICY_ENGINE_URL}"') == 1
|
|
79
|
+
assert '"https://agentgovern.onrender.com"' not in src
|
agentgovern-2.3.0/RELEASING.md
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Releasing agentgovern to PyPI
|
|
2
|
-
|
|
3
|
-
Releases are automated via `.github/workflows/publish-sdk.yml` using PyPI trusted publishing (OIDC — no API tokens needed). Pushing a `sdk-v*` tag triggers a build and publish automatically.
|
|
4
|
-
|
|
5
|
-
## Prerequisites (one-time PyPI setup)
|
|
6
|
-
|
|
7
|
-
Before the first automated publish, configure trusted publishing on PyPI:
|
|
8
|
-
|
|
9
|
-
1. Go to https://pypi.org/manage/project/agentgovern/settings/publishing/
|
|
10
|
-
2. Add a new trusted publisher with these exact values:
|
|
11
|
-
|
|
12
|
-
| Field | Value |
|
|
13
|
-
|-------------------|------------------------------|
|
|
14
|
-
| Owner | ZirahnAI |
|
|
15
|
-
| Repository name | agentgovern |
|
|
16
|
-
| Workflow filename | publish-sdk.yml |
|
|
17
|
-
| Environment name | pypi |
|
|
18
|
-
|
|
19
|
-
**Note:** the repository moved from `ahmedkhan-zirahn` to `ZirahnAI` in September 2026. A publisher for the old owner existed and was **deleted on 2026-09-14**. A trusted publisher that names a path the organisation no longer controls is a standing binding to a namespace someone else could later claim. See NAGT-314 in `docs/ROADMAP.md`.
|
|
20
|
-
|
|
21
|
-
3. Save. No API token needed after this.
|
|
22
|
-
|
|
23
|
-
Also create the `pypi` environment in GitHub:
|
|
24
|
-
- Go to https://github.com/ZirahnAI/agentgovern/settings/environments
|
|
25
|
-
- Create environment named `pypi` (no protection rules required)
|
|
26
|
-
|
|
27
|
-
## Release steps
|
|
28
|
-
|
|
29
|
-
1. **Bump the version** in two places:
|
|
30
|
-
```
|
|
31
|
-
packages/sdk-python/agentgovern/_version.py → __version__ = "0.X.Y"
|
|
32
|
-
packages/sdk-python/pyproject.toml → version = "0.X.Y"
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
2. **Add a CHANGELOG entry** (if `CHANGELOG.md` exists) describing what changed.
|
|
36
|
-
|
|
37
|
-
3. **Commit the version bump:**
|
|
38
|
-
```bash
|
|
39
|
-
git add packages/sdk-python/agentgovern/_version.py packages/sdk-python/pyproject.toml
|
|
40
|
-
git commit -m "chore(sdk): bump version to 0.X.Y"
|
|
41
|
-
git push
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
4. **Tag and push:**
|
|
45
|
-
```bash
|
|
46
|
-
git tag sdk-v0.X.Y
|
|
47
|
-
git push --tags
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
The `publish-sdk.yml` workflow triggers automatically on the tag push and publishes to PyPI.
|
|
51
|
-
|
|
52
|
-
5. **Verify** at https://pypi.org/project/agentgovern/ — the new version should appear within a few minutes.
|
|
53
|
-
|
|
54
|
-
## Manual fallback (workflow_dispatch)
|
|
55
|
-
|
|
56
|
-
If you need to publish without tagging (e.g., to re-publish after a failed run), trigger the workflow manually:
|
|
57
|
-
|
|
58
|
-
1. Go to https://github.com/ZirahnAI/agentgovern/actions/workflows/publish-sdk.yml
|
|
59
|
-
2. Click **Run workflow** → select branch `main` → **Run workflow**
|
|
60
|
-
|
|
61
|
-
The manual run builds and publishes whatever version is currently in `packages/sdk-python/pyproject.toml`. Make sure the version in `pyproject.toml` and `_version.py` match before triggering.
|
|
62
|
-
|
|
63
|
-
## First smoke test
|
|
64
|
-
|
|
65
|
-
Ahmed will run the first publish manually via `workflow_dispatch` before tagging any release. This confirms the OIDC trusted publisher config is wired correctly end-to-end.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.3.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|