bylaw-python 0.4.0__tar.gz → 0.5.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.
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/.shipsafeignore +2 -2
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/CHANGELOG.md +31 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/PKG-INFO +33 -33
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/README.md +32 -32
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/demo.py +5 -5
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/docs/MIGRATION_0.4.md +1 -1
- bylaw_python-0.5.0/docs/MIGRATION_0.5.md +81 -0
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/pyproject.toml +1 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/__init__.py +13 -13
- bylaw_python-0.5.0/src/bylaw_python/adapters/__init__.py +1 -0
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/adapters/_core.py +4 -4
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/adapters/crewai.py +15 -15
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/adapters/langchain.py +21 -21
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/adapters/llamaindex.py +13 -13
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/cli.py +41 -41
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/client.py +8 -8
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/config.py +8 -8
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/counterparty.py +1 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/enforce.py +31 -31
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/exceptions.py +10 -10
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/manifest.py +5 -5
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/models.py +1 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/pending.py +3 -3
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/src/bylaw_python/webhook.py +4 -4
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/conftest.py +6 -6
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_adapters.py +21 -21
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_client.py +36 -36
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_client_cache.py +16 -16
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_counterparty.py +4 -4
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_enforce.py +15 -15
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_jwks_kid_rotation.py +4 -4
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_manifest.py +21 -21
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_models.py +1 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_replay_detection.py +5 -5
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/test_retry_after.py +4 -4
- bylaw_python-0.5.0/uv.lock +5578 -0
- bylaw_python-0.4.0/src/bylaw_python/adapters/__init__.py +0 -1
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/.github/workflows/ci.yml +0 -0
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/.gitignore +0 -0
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/requirements.txt +0 -0
- {bylaw_python-0.4.0 → bylaw_python-0.5.0}/tests/__init__.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Ship Safe ignore rules for python-sdk
|
|
2
|
-
# Published as
|
|
2
|
+
# Published as bylaw-python on PyPI. Agent-agnostic SDK shim.
|
|
3
3
|
|
|
4
4
|
# --- Test fixtures ---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ Generic API Key Assignment
|
|
|
9
9
|
# Test assertions use == for values, not secrets.
|
|
10
10
|
TIMING_ATTACK_COMPARISON
|
|
11
11
|
|
|
12
|
-
# --- CLI (
|
|
12
|
+
# --- CLI (bylaw init / status / teardown) ---
|
|
13
13
|
|
|
14
14
|
# CLI commands invoke docker-compose and subprocess.run for local dev
|
|
15
15
|
# orchestration. These are user-invoked commands, not LLM-driven actions.
|
|
@@ -5,6 +5,36 @@ All notable changes to `bylaw-python` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0]
|
|
9
|
+
|
|
10
|
+
### Breaking changes — Ledgix → Bylaw rebrand
|
|
11
|
+
|
|
12
|
+
The SDK has been rebranded from Ledgix to Bylaw. See
|
|
13
|
+
[`docs/MIGRATION_0.5.md`](docs/MIGRATION_0.5.md) for the full migration guide.
|
|
14
|
+
|
|
15
|
+
#### Package & CLI
|
|
16
|
+
- PyPI package: `bylaw-python` (replaces `ledgix-python`)
|
|
17
|
+
- CLI command: `bylaw` (replaces `ledgix`)
|
|
18
|
+
- Import path: `bylaw_python` (replaces `ledgix_python`)
|
|
19
|
+
|
|
20
|
+
#### Renamed public API
|
|
21
|
+
- `LedgixClient` → `BylawClient`
|
|
22
|
+
- `LedgixError` → `BylawError`
|
|
23
|
+
- `LedgixCallbackHandler` → `BylawCallbackHandler`
|
|
24
|
+
- `LedgixTool` → `BylawTool` (LangChain adapter)
|
|
25
|
+
- `LedgixToolWrapper` → `BylawToolWrapper` (LlamaIndex adapter)
|
|
26
|
+
- `LedgixCrewAITool` → `BylawCrewAITool`
|
|
27
|
+
|
|
28
|
+
#### Configuration
|
|
29
|
+
- Environment variable prefix: `BYLAW_` (replaces `LEDGIX_`)
|
|
30
|
+
- Manifest filenames: `bylaw.yaml` / `bylaw.yml` / `bylaw.json` (replaces `ledgix.*`)
|
|
31
|
+
- Dev compose file: `docker-compose.bylaw.yml` (replaces `docker-compose.ledgix.yml`)
|
|
32
|
+
|
|
33
|
+
#### Unchanged (Vault wire protocol)
|
|
34
|
+
- JWT audience default remains `ledgix-sdk` until the Vault server rebrand ships
|
|
35
|
+
- Audit ledger hash prefixes (`ledgix.audit.*`) unchanged for merkle compatibility
|
|
36
|
+
- Webhook header `X-Ledgix-Signature` unchanged until Vault emits the new header
|
|
37
|
+
|
|
8
38
|
## [0.4.0]
|
|
9
39
|
|
|
10
40
|
### Breaking changes — categorical confidence buckets
|
|
@@ -71,7 +101,7 @@ couldn't reliably produce and gives review-pending its own dedicated state.
|
|
|
71
101
|
breakdowns.
|
|
72
102
|
- All four fields are also surfaced as kwargs on `enforce()`, `tool()`,
|
|
73
103
|
`vault_enforce()`, and `VaultContext` so the high-level decorator API
|
|
74
|
-
can populate them without dropping to `
|
|
104
|
+
can populate them without dropping to `BylawClient.request_clearance`.
|
|
75
105
|
- `/mint-token` cache-replay forwards the new fields alongside the 0.3.0
|
|
76
106
|
destination set.
|
|
77
107
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bylaw-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Agent-agnostic compliance shim for SOX 404 policy enforcement via the ALCV Vault
|
|
5
5
|
Project-URL: Homepage, https://github.com/bylaw-dev/python-sdk
|
|
6
6
|
Project-URL: Documentation, https://docs.bylaw.dev
|
|
@@ -42,9 +42,9 @@ Provides-Extra: yaml
|
|
|
42
42
|
Requires-Dist: pyyaml>=6.0; extra == 'yaml'
|
|
43
43
|
Description-Content-Type: text/markdown
|
|
44
44
|
|
|
45
|
-
#
|
|
45
|
+
# Bylaw ALCV — Python SDK
|
|
46
46
|
|
|
47
|
-
[](https://pypi.org/project/bylaw-python/)
|
|
48
48
|
[](https://python.org)
|
|
49
49
|
[](LICENSE)
|
|
50
50
|
|
|
@@ -57,7 +57,7 @@ pip install bylaw-python
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
```python
|
|
60
|
-
#
|
|
60
|
+
# bylaw.yaml
|
|
61
61
|
# enforce:
|
|
62
62
|
# - tool: "stripe_*"
|
|
63
63
|
# policy_id: "financial-high-risk"
|
|
@@ -65,53 +65,53 @@ pip install bylaw-python
|
|
|
65
65
|
# policy_id: "default"
|
|
66
66
|
|
|
67
67
|
import tools
|
|
68
|
-
import bylaw_python as
|
|
68
|
+
import bylaw_python as bylaw
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
bylaw.configure(agent_id="payments-agent")
|
|
71
|
+
bylaw.auto_instrument(tools)
|
|
72
72
|
|
|
73
73
|
result = tools.stripe_refund(45, "Late package")
|
|
74
74
|
print(result)
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
`auto_instrument()` reads `
|
|
77
|
+
`auto_instrument()` reads `bylaw.yaml`, `bylaw.yml`, or `bylaw.json` from the current working directory by default, wraps matching functions in place, and leaves unmatched functions alone.
|
|
78
78
|
|
|
79
79
|
## Configuration
|
|
80
80
|
|
|
81
|
-
Set environment variables (prefix: `
|
|
81
|
+
Set environment variables (prefix: `BYLAW_`):
|
|
82
82
|
|
|
83
83
|
| Variable | Default | Description |
|
|
84
84
|
|---|---|---|
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
85
|
+
| `BYLAW_VAULT_URL` | `http://localhost:8000` | Vault server URL |
|
|
86
|
+
| `BYLAW_VAULT_API_KEY` | `""` | API key for Vault auth |
|
|
87
|
+
| `BYLAW_VAULT_TIMEOUT` | `30.0` | Request timeout (seconds) |
|
|
88
|
+
| `BYLAW_VERIFY_JWT` | `true` | Verify A-JWT signatures |
|
|
89
|
+
| `BYLAW_JWT_ISSUER` | `alcv-vault` | Expected A-JWT issuer |
|
|
90
|
+
| `BYLAW_JWT_AUDIENCE` | `ledgix-sdk` | Expected A-JWT audience |
|
|
91
|
+
| `BYLAW_AGENT_ID` | `default-agent` | Agent identifier |
|
|
92
92
|
|
|
93
93
|
Or pass a `VaultConfig` directly:
|
|
94
94
|
|
|
95
95
|
```python
|
|
96
|
-
from bylaw_python import
|
|
96
|
+
from bylaw_python import BylawClient, VaultConfig
|
|
97
97
|
|
|
98
98
|
config = VaultConfig(vault_url="https://vault.mycompany.com", vault_api_key="sk-...")
|
|
99
|
-
client =
|
|
99
|
+
client = BylawClient(config=config)
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
## Manifest-driven auto-instrumentation
|
|
103
103
|
|
|
104
104
|
```python
|
|
105
105
|
import tools
|
|
106
|
-
import bylaw_python as
|
|
106
|
+
import bylaw_python as bylaw
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
bylaw.configure(agent_id="payments-agent")
|
|
109
109
|
|
|
110
|
-
# Auto-discover
|
|
111
|
-
wrapped =
|
|
110
|
+
# Auto-discover bylaw.yaml / bylaw.yml / bylaw.json from the CWD
|
|
111
|
+
wrapped = bylaw.auto_instrument(tools)
|
|
112
112
|
|
|
113
113
|
# Or pass an inline manifest
|
|
114
|
-
|
|
114
|
+
bylaw.auto_instrument(
|
|
115
115
|
tools,
|
|
116
116
|
manifest={"enforce": [{"tool": "stripe_*", "policy_id": "financial-high-risk"}]},
|
|
117
117
|
)
|
|
@@ -126,13 +126,13 @@ pip install bylaw-python[yaml]
|
|
|
126
126
|
### Escape hatch
|
|
127
127
|
|
|
128
128
|
```python
|
|
129
|
-
@
|
|
129
|
+
@bylaw.tool
|
|
130
130
|
def special_refund(amount: float):
|
|
131
|
-
return
|
|
131
|
+
return bylaw.current_token()
|
|
132
132
|
|
|
133
|
-
@
|
|
133
|
+
@bylaw.tool(policy_id="override-policy")
|
|
134
134
|
def stripe_charge(amount: float):
|
|
135
|
-
return
|
|
135
|
+
return bylaw.current_token()
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
## Framework Adapters
|
|
@@ -144,14 +144,14 @@ pip install bylaw-python[langchain]
|
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
```python
|
|
147
|
-
from bylaw_python.adapters.langchain import
|
|
147
|
+
from bylaw_python.adapters.langchain import BylawCallbackHandler, BylawTool
|
|
148
148
|
|
|
149
149
|
# Option 1: Callback handler (intercepts ALL tool calls)
|
|
150
|
-
handler =
|
|
150
|
+
handler = BylawCallbackHandler(client)
|
|
151
151
|
agent = create_agent(callbacks=[handler])
|
|
152
152
|
|
|
153
153
|
# Option 2: Wrap individual tools
|
|
154
|
-
guarded_tool =
|
|
154
|
+
guarded_tool = BylawTool.wrap(client, my_tool, policy_id="refund-policy")
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
### LlamaIndex
|
|
@@ -173,9 +173,9 @@ pip install bylaw-python[crewai]
|
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
```python
|
|
176
|
-
from bylaw_python.adapters.crewai import
|
|
176
|
+
from bylaw_python.adapters.crewai import BylawCrewAITool
|
|
177
177
|
|
|
178
|
-
guarded_tool =
|
|
178
|
+
guarded_tool = BylawCrewAITool.wrap(client, my_tool, policy_id="refund-policy")
|
|
179
179
|
```
|
|
180
180
|
|
|
181
181
|
## Context Manager
|
|
@@ -209,7 +209,7 @@ except TokenVerificationError:
|
|
|
209
209
|
## Development
|
|
210
210
|
|
|
211
211
|
```bash
|
|
212
|
-
git clone https://github.com/
|
|
212
|
+
git clone https://github.com/bylaw-dev/python-sdk.git
|
|
213
213
|
cd python-sdk
|
|
214
214
|
python -m venv .venv && source .venv/bin/activate
|
|
215
215
|
pip install -e ".[dev]"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bylaw ALCV — Python SDK
|
|
2
2
|
|
|
3
|
-
[](https://pypi.org/project/bylaw-python/)
|
|
4
4
|
[](https://python.org)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@ pip install bylaw-python
|
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
```python
|
|
16
|
-
#
|
|
16
|
+
# bylaw.yaml
|
|
17
17
|
# enforce:
|
|
18
18
|
# - tool: "stripe_*"
|
|
19
19
|
# policy_id: "financial-high-risk"
|
|
@@ -21,53 +21,53 @@ pip install bylaw-python
|
|
|
21
21
|
# policy_id: "default"
|
|
22
22
|
|
|
23
23
|
import tools
|
|
24
|
-
import bylaw_python as
|
|
24
|
+
import bylaw_python as bylaw
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
bylaw.configure(agent_id="payments-agent")
|
|
27
|
+
bylaw.auto_instrument(tools)
|
|
28
28
|
|
|
29
29
|
result = tools.stripe_refund(45, "Late package")
|
|
30
30
|
print(result)
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
`auto_instrument()` reads `
|
|
33
|
+
`auto_instrument()` reads `bylaw.yaml`, `bylaw.yml`, or `bylaw.json` from the current working directory by default, wraps matching functions in place, and leaves unmatched functions alone.
|
|
34
34
|
|
|
35
35
|
## Configuration
|
|
36
36
|
|
|
37
|
-
Set environment variables (prefix: `
|
|
37
|
+
Set environment variables (prefix: `BYLAW_`):
|
|
38
38
|
|
|
39
39
|
| Variable | Default | Description |
|
|
40
40
|
|---|---|---|
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
41
|
+
| `BYLAW_VAULT_URL` | `http://localhost:8000` | Vault server URL |
|
|
42
|
+
| `BYLAW_VAULT_API_KEY` | `""` | API key for Vault auth |
|
|
43
|
+
| `BYLAW_VAULT_TIMEOUT` | `30.0` | Request timeout (seconds) |
|
|
44
|
+
| `BYLAW_VERIFY_JWT` | `true` | Verify A-JWT signatures |
|
|
45
|
+
| `BYLAW_JWT_ISSUER` | `alcv-vault` | Expected A-JWT issuer |
|
|
46
|
+
| `BYLAW_JWT_AUDIENCE` | `ledgix-sdk` | Expected A-JWT audience |
|
|
47
|
+
| `BYLAW_AGENT_ID` | `default-agent` | Agent identifier |
|
|
48
48
|
|
|
49
49
|
Or pass a `VaultConfig` directly:
|
|
50
50
|
|
|
51
51
|
```python
|
|
52
|
-
from bylaw_python import
|
|
52
|
+
from bylaw_python import BylawClient, VaultConfig
|
|
53
53
|
|
|
54
54
|
config = VaultConfig(vault_url="https://vault.mycompany.com", vault_api_key="sk-...")
|
|
55
|
-
client =
|
|
55
|
+
client = BylawClient(config=config)
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## Manifest-driven auto-instrumentation
|
|
59
59
|
|
|
60
60
|
```python
|
|
61
61
|
import tools
|
|
62
|
-
import bylaw_python as
|
|
62
|
+
import bylaw_python as bylaw
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
bylaw.configure(agent_id="payments-agent")
|
|
65
65
|
|
|
66
|
-
# Auto-discover
|
|
67
|
-
wrapped =
|
|
66
|
+
# Auto-discover bylaw.yaml / bylaw.yml / bylaw.json from the CWD
|
|
67
|
+
wrapped = bylaw.auto_instrument(tools)
|
|
68
68
|
|
|
69
69
|
# Or pass an inline manifest
|
|
70
|
-
|
|
70
|
+
bylaw.auto_instrument(
|
|
71
71
|
tools,
|
|
72
72
|
manifest={"enforce": [{"tool": "stripe_*", "policy_id": "financial-high-risk"}]},
|
|
73
73
|
)
|
|
@@ -82,13 +82,13 @@ pip install bylaw-python[yaml]
|
|
|
82
82
|
### Escape hatch
|
|
83
83
|
|
|
84
84
|
```python
|
|
85
|
-
@
|
|
85
|
+
@bylaw.tool
|
|
86
86
|
def special_refund(amount: float):
|
|
87
|
-
return
|
|
87
|
+
return bylaw.current_token()
|
|
88
88
|
|
|
89
|
-
@
|
|
89
|
+
@bylaw.tool(policy_id="override-policy")
|
|
90
90
|
def stripe_charge(amount: float):
|
|
91
|
-
return
|
|
91
|
+
return bylaw.current_token()
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
## Framework Adapters
|
|
@@ -100,14 +100,14 @@ pip install bylaw-python[langchain]
|
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
```python
|
|
103
|
-
from bylaw_python.adapters.langchain import
|
|
103
|
+
from bylaw_python.adapters.langchain import BylawCallbackHandler, BylawTool
|
|
104
104
|
|
|
105
105
|
# Option 1: Callback handler (intercepts ALL tool calls)
|
|
106
|
-
handler =
|
|
106
|
+
handler = BylawCallbackHandler(client)
|
|
107
107
|
agent = create_agent(callbacks=[handler])
|
|
108
108
|
|
|
109
109
|
# Option 2: Wrap individual tools
|
|
110
|
-
guarded_tool =
|
|
110
|
+
guarded_tool = BylawTool.wrap(client, my_tool, policy_id="refund-policy")
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### LlamaIndex
|
|
@@ -129,9 +129,9 @@ pip install bylaw-python[crewai]
|
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
```python
|
|
132
|
-
from bylaw_python.adapters.crewai import
|
|
132
|
+
from bylaw_python.adapters.crewai import BylawCrewAITool
|
|
133
133
|
|
|
134
|
-
guarded_tool =
|
|
134
|
+
guarded_tool = BylawCrewAITool.wrap(client, my_tool, policy_id="refund-policy")
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
## Context Manager
|
|
@@ -165,7 +165,7 @@ except TokenVerificationError:
|
|
|
165
165
|
## Development
|
|
166
166
|
|
|
167
167
|
```bash
|
|
168
|
-
git clone https://github.com/
|
|
168
|
+
git clone https://github.com/bylaw-dev/python-sdk.git
|
|
169
169
|
cd python-sdk
|
|
170
170
|
python -m venv .venv && source .venv/bin/activate
|
|
171
171
|
pip install -e ".[dev]"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""Bylaw ALCV SDK — Demo Script
|
|
3
3
|
|
|
4
4
|
Simulates the "Good Agent" vs "Rogue Agent" scenario from the
|
|
5
5
|
ALCV Vault technical specification.
|
|
6
6
|
|
|
7
7
|
This demo runs without a real Vault server by using a lightweight
|
|
8
|
-
mock. Set
|
|
8
|
+
mock. Set BYLAW_VAULT_URL to point to a real Vault to test live.
|
|
9
9
|
|
|
10
10
|
Usage:
|
|
11
11
|
python demo.py
|
|
@@ -23,7 +23,7 @@ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
|
|
23
23
|
|
|
24
24
|
from bylaw_python import (
|
|
25
25
|
ClearanceDeniedError,
|
|
26
|
-
|
|
26
|
+
BylawClient,
|
|
27
27
|
VaultConfig,
|
|
28
28
|
vault_enforce,
|
|
29
29
|
)
|
|
@@ -112,7 +112,7 @@ def run_demo():
|
|
|
112
112
|
"""Run the Good Agent / Rogue Agent demo."""
|
|
113
113
|
|
|
114
114
|
print("=" * 64)
|
|
115
|
-
print("
|
|
115
|
+
print(" BYLAW ALCV — SDK Demo")
|
|
116
116
|
print(" Policy: \"Refunds ≤ $100 for shipping delays only\"")
|
|
117
117
|
print("=" * 64)
|
|
118
118
|
|
|
@@ -123,7 +123,7 @@ def run_demo():
|
|
|
123
123
|
verify_jwt=False,
|
|
124
124
|
agent_id="demo-agent",
|
|
125
125
|
)
|
|
126
|
-
client =
|
|
126
|
+
client = BylawClient(config=config)
|
|
127
127
|
|
|
128
128
|
# ── Scenario A: Good Agent ─────────────────────────────────────
|
|
129
129
|
print("\n" + "─" * 64)
|
|
@@ -132,7 +132,7 @@ failure modes that the bucket migration eliminates:
|
|
|
132
132
|
## Where to ask questions
|
|
133
133
|
|
|
134
134
|
- General SDK questions: file an issue on the `bylaw-python` repo.
|
|
135
|
-
- Migration help: ping `team@
|
|
135
|
+
- Migration help: ping `team@bylaw.dev` with `[0.4 migration]` in the
|
|
136
136
|
subject line.
|
|
137
137
|
- Vault wire-format questions: see the `vault` repo's
|
|
138
138
|
`docs/api/clearance.md`.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Migration Guide: 0.4.x → 0.5.0 (Ledgix → Bylaw)
|
|
2
|
+
|
|
3
|
+
Version 0.5.0 completes the Ledgix → Bylaw rebrand. This is a breaking release
|
|
4
|
+
for anyone still on the old package name or API symbols.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip uninstall ledgix-python # if previously installed
|
|
10
|
+
pip install bylaw-python
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Import path
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
# Before
|
|
17
|
+
import ledgix_python as ledgix
|
|
18
|
+
|
|
19
|
+
# After
|
|
20
|
+
import bylaw_python as bylaw
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Renamed classes
|
|
24
|
+
|
|
25
|
+
| Before | After |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `LedgixClient` | `BylawClient` |
|
|
28
|
+
| `LedgixError` | `BylawError` |
|
|
29
|
+
| `LedgixCallbackHandler` | `BylawCallbackHandler` |
|
|
30
|
+
| `LedgixTool` | `BylawTool` |
|
|
31
|
+
| `LedgixToolWrapper` | `BylawToolWrapper` |
|
|
32
|
+
| `LedgixCrewAITool` | `BylawCrewAITool` |
|
|
33
|
+
|
|
34
|
+
## Environment variables
|
|
35
|
+
|
|
36
|
+
All `LEDGIX_*` variables are now `BYLAW_*`:
|
|
37
|
+
|
|
38
|
+
| Before | After |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `LEDGIX_VAULT_URL` | `BYLAW_VAULT_URL` |
|
|
41
|
+
| `LEDGIX_VAULT_API_KEY` | `BYLAW_VAULT_API_KEY` |
|
|
42
|
+
| `LEDGIX_AGENT_ID` | `BYLAW_AGENT_ID` |
|
|
43
|
+
| `LEDGIX_JWT_AUDIENCE` | `BYLAW_JWT_AUDIENCE` |
|
|
44
|
+
|
|
45
|
+
## Manifest files
|
|
46
|
+
|
|
47
|
+
Rename your manifest file:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
mv ledgix.yaml bylaw.yaml # or .yml / .json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## CLI
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Before
|
|
57
|
+
ledgix init
|
|
58
|
+
ledgix status
|
|
59
|
+
ledgix teardown
|
|
60
|
+
|
|
61
|
+
# After
|
|
62
|
+
bylaw init
|
|
63
|
+
bylaw status
|
|
64
|
+
bylaw teardown
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Local dev scaffolding now writes `docker-compose.bylaw.yml` and `.env.bylaw`.
|
|
68
|
+
|
|
69
|
+
## Vault wire protocol (unchanged)
|
|
70
|
+
|
|
71
|
+
These values remain the same until the Vault server-side rebrand ships:
|
|
72
|
+
|
|
73
|
+
- JWT audience default: `ledgix-sdk`
|
|
74
|
+
- Webhook signature header: `X-Ledgix-Signature`
|
|
75
|
+
- Audit ledger hash domain: `ledgix.audit.event.v1` / `ledgix.audit.checkpoint.v1`
|
|
76
|
+
|
|
77
|
+
No action required unless you explicitly overrode these in your config.
|
|
78
|
+
|
|
79
|
+
## Need help?
|
|
80
|
+
|
|
81
|
+
Contact `team@bylaw.dev` with `[0.5 migration]` in the subject line.
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bylaw ALCV — Python SDK
|
|
2
2
|
# Agent-agnostic compliance shim for SOX 404 policy enforcement
|
|
3
3
|
#
|
|
4
4
|
# Recommended usage:
|
|
5
|
-
# import bylaw_python as
|
|
5
|
+
# import bylaw_python as bylaw
|
|
6
6
|
#
|
|
7
|
-
#
|
|
7
|
+
# bylaw.configure(agent_id="finance-agent")
|
|
8
8
|
#
|
|
9
9
|
# import tools
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
11
|
+
# bylaw.configure(agent_id="finance-agent")
|
|
12
|
+
# bylaw.auto_instrument(tools)
|
|
13
13
|
#
|
|
14
14
|
# Explicit API (advanced):
|
|
15
|
-
# from bylaw_python import
|
|
15
|
+
# from bylaw_python import BylawClient, vault_enforce, VaultConfig
|
|
16
16
|
#
|
|
17
|
-
# client =
|
|
17
|
+
# client = BylawClient()
|
|
18
18
|
#
|
|
19
19
|
# @vault_enforce(client, tool_name="stripe_refund")
|
|
20
20
|
# def process_refund(amount: float, reason: str, **kwargs):
|
|
21
21
|
# token = kwargs.get("_clearance").token
|
|
22
22
|
# ...
|
|
23
23
|
|
|
24
|
-
"""
|
|
24
|
+
"""Bylaw ALCV — agent-agnostic compliance shim for SOX 404 enforcement."""
|
|
25
25
|
|
|
26
|
-
from .client import
|
|
26
|
+
from .client import BylawClient
|
|
27
27
|
from .config import VaultConfig
|
|
28
28
|
from .enforce import (
|
|
29
29
|
VaultContext,
|
|
@@ -40,7 +40,7 @@ from .exceptions import (
|
|
|
40
40
|
ClearanceDeniedError,
|
|
41
41
|
ManualReviewTimeoutError,
|
|
42
42
|
PolicyRegistrationError,
|
|
43
|
-
|
|
43
|
+
BylawError,
|
|
44
44
|
QueueSaturatedError,
|
|
45
45
|
ReplayDetectedError,
|
|
46
46
|
ReviewPendingError,
|
|
@@ -64,11 +64,11 @@ from .models import (
|
|
|
64
64
|
PolicyRegistrationResponse,
|
|
65
65
|
)
|
|
66
66
|
|
|
67
|
-
__version__ = "0.
|
|
67
|
+
__version__ = "0.5.0"
|
|
68
68
|
|
|
69
69
|
__all__ = [
|
|
70
70
|
# Core
|
|
71
|
-
"
|
|
71
|
+
"BylawClient",
|
|
72
72
|
"VaultConfig",
|
|
73
73
|
# Low-code API
|
|
74
74
|
"configure",
|
|
@@ -102,7 +102,7 @@ __all__ = [
|
|
|
102
102
|
"PolicyRegistration",
|
|
103
103
|
"PolicyRegistrationResponse",
|
|
104
104
|
# Exceptions
|
|
105
|
-
"
|
|
105
|
+
"BylawError",
|
|
106
106
|
"ClearanceDeniedError",
|
|
107
107
|
"ManualReviewTimeoutError",
|
|
108
108
|
"QueueSaturatedError",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Bylaw ALCV — Framework Adapters
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bylaw ALCV — Adapter Core Helpers
|
|
2
2
|
# Shared scaffolding used by the LangChain, LlamaIndex, and CrewAI adapters.
|
|
3
3
|
# Framework-specific glue (callback handlers, sync vs async, error-translation
|
|
4
4
|
# policy) stays per-adapter — only the genuinely identical pieces live here.
|
|
@@ -7,12 +7,12 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
|
-
from ..client import
|
|
10
|
+
from ..client import BylawClient
|
|
11
11
|
from ..enforce import _get_default_client
|
|
12
12
|
from ..models import ClearanceRequest
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def resolve_client(client:
|
|
15
|
+
def resolve_client(client: BylawClient | None) -> BylawClient:
|
|
16
16
|
"""Return the explicit client or fall back to the module-level default
|
|
17
17
|
configured via :func:`bylaw_python.configure`.
|
|
18
18
|
"""
|
|
@@ -25,7 +25,7 @@ def build_clearance_request(
|
|
|
25
25
|
*,
|
|
26
26
|
tool_name: str,
|
|
27
27
|
tool_args: dict[str, Any],
|
|
28
|
-
client:
|
|
28
|
+
client: BylawClient,
|
|
29
29
|
policy_id: str | None = None,
|
|
30
30
|
extra_context: dict[str, Any] | None = None,
|
|
31
31
|
data_categories: list[str] | None = None,
|