banza-conformance 0.1.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.
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: banza-conformance
3
+ Version: 0.1.0
4
+ Summary: BANZA protocol conformance runner — generates conformance evidence (not certification) for an operator endpoint.
5
+ Author: BANZA Protocol
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://banza.org/conformance
8
+ Project-URL: Source, https://github.com/banza-protocol/banza
9
+ Keywords: banza,conformance,protocol,evidence
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Provides-Extra: federation
13
+ Requires-Dist: cryptography>=41.0.0; extra == "federation"
14
+
15
+ # Banza Conformance Runner
16
+
17
+ Tests a running Banza operator against the protocol conformance suite and produces a structured JSON report.
18
+
19
+ > The runner generates **conformance evidence, not certification**. A PASS is technical
20
+ > conformance evidence for the requested level — it is **not** a production certificate.
21
+ > Production certification remains M2/M3-gated and is issued separately by the BANZA CA.
22
+
23
+ ## Distribution for external operators
24
+
25
+ External operators can run BANZA conformance against their **public sandbox endpoint**
26
+ without cloning this repository, in three ways.
27
+
28
+ ### Installable CLI
29
+
30
+ ```bash
31
+ pip install banza-conformance # from tools/banza-conformance
32
+ banza-conformance --url https://sandbox.operator.example --level 0 --output report.json
33
+ ```
34
+
35
+ Supported options: `--url` (required), `--level`, `--suite`, `--output`, `--quiet`,
36
+ `--federation` (L3, requires the `federation` extra: `pip install "banza-conformance[federation]"`).
37
+ The CLI calls the same conformance logic as `run.py` — `python3 tools/banza-conformance/run.py …`
38
+ continues to work unchanged.
39
+
40
+ On completion the tool prints:
41
+
42
+ ```
43
+ Conformance report generated. This is evidence, not certification.
44
+ ```
45
+
46
+ ### Client identity (User-Agent)
47
+
48
+ The runner sends a stable, documented User-Agent so operators can allow it in
49
+ WAF / proxy / CDN configurations:
50
+
51
+ ```
52
+ BANZA-Conformance/1.0 (+https://banza.org/conformance)
53
+ ```
54
+
55
+ If your sandbox endpoint sits behind a bot filter (e.g. Cloudflare), allow this
56
+ User-Agent (or the `/health` and `/.well-known/banza/*` paths) so the runner can reach it.
57
+ The User-Agent identifies the client cleanly; it does not bypass any security control.
58
+
59
+ ### Docker
60
+
61
+ ```bash
62
+ docker run --rm \
63
+ -v "$PWD/reports:/reports" \
64
+ ghcr.io/banza-protocol/banza-conformance:latest \
65
+ --url https://sandbox.operator.example \
66
+ --level 0 \
67
+ --output /reports/banza-l0-report.json
68
+ ```
69
+
70
+ Build the image locally (context = this directory):
71
+
72
+ ```bash
73
+ docker build -t banza-conformance:local tools/banza-conformance
74
+ ```
75
+
76
+ The entrypoint is `banza-conformance`; arguments after the image name are passed
77
+ straight through. Reports are written under `/reports` — mount a host volume there.
78
+
79
+ ### GitHub Action
80
+
81
+ Run BANZA conformance in your CI/CD against your public sandbox endpoint:
82
+
83
+ ```yaml
84
+ name: BANZA Conformance
85
+
86
+ on:
87
+ workflow_dispatch:
88
+ pull_request:
89
+ push:
90
+
91
+ jobs:
92
+ conformance:
93
+ runs-on: ubuntu-latest
94
+ steps:
95
+ - uses: actions/checkout@v4
96
+ - uses: banza-protocol/banza/.github/actions/banza-conformance@main
97
+ with:
98
+ url: https://sandbox.operator.example
99
+ level: "0"
100
+ output: banza-l0-report.json
101
+ - uses: actions/upload-artifact@v4
102
+ with:
103
+ name: banza-conformance-report
104
+ path: banza-l0-report.json
105
+ ```
106
+
107
+ Inputs: `url` (required), `level` (default `"0"`), `output`
108
+ (default `"banza-conformance-report.json"`), `suite`, `federation`, `quiet`.
109
+
110
+ ## Requirements
111
+
112
+ Python 3.8+. No third-party packages for the core runner — stdlib only.
113
+
114
+ For L3 federation conformance (signature verification): `pip install cryptography>=41.0.0`
115
+
116
+ ## Usage
117
+
118
+ ### Standard conformance (L0–L4)
119
+
120
+ ```bash
121
+ # Run all suites against a local operator
122
+ python3 tools/banza-conformance/run.py --url http://localhost:3000
123
+
124
+ # Run up to Level 2 only
125
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --level 2
126
+
127
+ # Run a single suite
128
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --suite health
129
+
130
+ # Write report to file (quiet mode)
131
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --output report.json --quiet
132
+ ```
133
+
134
+ Or via the shell wrapper:
135
+
136
+ ```bash
137
+ ./tools/banza-conformance/run.sh --url http://localhost:3000 --output report.json
138
+ ```
139
+
140
+ ### L3 Federation Conformance (79 tests, 9 suites)
141
+
142
+ The federation conformance suite tests cross-operator federation protocol compliance.
143
+ It requires two terminals: one for the fixture server (Operator A adapter) and one for the runner.
144
+
145
+ ```bash
146
+ # Terminal 1 — start the fixture server (Operator A)
147
+ python3 tools/banza-conformance/fixture_server.py --port 8099
148
+
149
+ # Terminal 2 — run the full federation suite (79 tests)
150
+ python3 tools/banza-conformance/run.py \
151
+ --federation \
152
+ --url http://localhost:8099 \
153
+ --output l3-report.json
154
+
155
+ # Run only one federation sub-suite
156
+ python3 tools/banza-conformance/run.py \
157
+ --federation \
158
+ --url http://localhost:8099 \
159
+ --fed-suite cert # cert | disc | trust | route | exec | obl | evt | settle | fail
160
+ ```
161
+
162
+ **What the federation runner does:**
163
+ - Generates an ephemeral test BANZA root keypair (never reused as production)
164
+ - Spins up an embedded Simulated Operator B (random port, in-process)
165
+ - Spins up an embedded test BRL/key-manifest server (random port, in-process)
166
+ - Runs all 79 federation tests against the fixture server
167
+ - Produces a structured JSON evidence report
168
+
169
+ **Federation suites:**
170
+
171
+ | Suite | Cases | Blocking | What it tests |
172
+ |---|---|---|---|
173
+ | FED-CERT | 11 | Yes | Certificate schema, signature, expiry, BRL |
174
+ | FED-DISC | 8 | Yes | Federation manifest extension fields |
175
+ | FED-TRUST | 9 | Yes | All 9 ADR-026 trust protocol steps |
176
+ | FED-ROUTE | 12 | Yes | Routing wire protocol, idempotency, rejections |
177
+ | FED-EXEC | 8 | Yes | Acceptance semantics, ledger atomicity |
178
+ | FED-OBL | 7 | Yes | Obligation creation, signature, state machine |
179
+ | FED-EVT | 6 | No | Federation event emission and schema |
180
+ | FED-SETTLE | 10 | No | Netting, settlement, reconciliation |
181
+ | FED-FAIL | 8 | No | Retry, crash recovery, revocation, mismatches |
182
+
183
+ **L3 certification decision:** All blocking suites (FED-CERT through FED-OBL) must PASS. FAIL in a blocking suite denies certification. FAIL in a non-blocking suite produces conditional certification (30-day remediation window).
184
+
185
+ See `docs/federation/FEDERATION_CONFORMANCE_MODEL.md` for the full decision rules.
186
+
187
+ ## Options
188
+
189
+ | Flag | Description |
190
+ |------|-------------|
191
+ | `--url` | Base URL of the operator (required) |
192
+ | `--level` | Maximum certification level to test, 0–4 (default 4) |
193
+ | `--suite` | Run one suite only: `health`, `wallets`, `transfers`, `traces`, `manifest` |
194
+ | `--output` | Write JSON report to this path (default: stdout) |
195
+ | `--quiet` | Suppress PASS lines; only print failures and summary |
196
+
197
+ ## Certification levels
198
+
199
+ | Level | Name | Runner suites | Awarded here |
200
+ |-------|------|---------------|--------------|
201
+ | L0 | Protocol Sandbox | health, manifest (sandbox-safety) | Yes |
202
+ | L1 | Core Payment Capability | + wallets, transfers, traces (traceability) | Yes |
203
+ | L2 | Payment Initiation Capability | + payment_initiation (payment requests, dynamic QR, instant execution) | Yes |
204
+ | L3 | Inter-Operator Interoperability | federation suite — run via `--federation` (`run_fed.py`) | No (multi-operator) |
205
+ | L4 | External Interoperability | External Interoperability profile (external-rail evidence) | No (profile) |
206
+
207
+ Level names **and per-level capabilities** are canonical and match
208
+ `BANZA_CERTIFICATION.md` § Conformance level model and ADR-034. This
209
+ single-operator sandbox runner awards **L0–L2**; L3 (federation) and L4 (external)
210
+ require multi-operator / external-rail evidence and are not awarded here.
211
+
212
+ ## Exit codes
213
+
214
+ | Code | Meaning |
215
+ |------|---------|
216
+ | 0 | All executed cases passed |
217
+ | 1 | One or more cases failed |
218
+ | 2 | Runner error (connectivity, bad arguments) |
219
+
220
+ ## Report format
221
+
222
+ Reports conform to `conformance/report-schema.json`. Each case records:
223
+ - `status`: PASS / FAIL / SKIP / ERROR
224
+ - `request` and `response` for HTTP cases
225
+ - `assertions`: per-field check results
226
+ - `failure_reason`: human-readable explanation on failure
227
+
228
+ ## Adding new suites
229
+
230
+ 1. Implement a runner function `run_<name>(base_url, ctx) -> list[CaseResult]`
231
+ 2. Register it in the `SUITES` dict
232
+ 3. Add it to the relevant `LEVEL_SUITES` entries
233
+ 4. Add the corresponding vectors in `conformance/vectors/`
@@ -0,0 +1,219 @@
1
+ # Banza Conformance Runner
2
+
3
+ Tests a running Banza operator against the protocol conformance suite and produces a structured JSON report.
4
+
5
+ > The runner generates **conformance evidence, not certification**. A PASS is technical
6
+ > conformance evidence for the requested level — it is **not** a production certificate.
7
+ > Production certification remains M2/M3-gated and is issued separately by the BANZA CA.
8
+
9
+ ## Distribution for external operators
10
+
11
+ External operators can run BANZA conformance against their **public sandbox endpoint**
12
+ without cloning this repository, in three ways.
13
+
14
+ ### Installable CLI
15
+
16
+ ```bash
17
+ pip install banza-conformance # from tools/banza-conformance
18
+ banza-conformance --url https://sandbox.operator.example --level 0 --output report.json
19
+ ```
20
+
21
+ Supported options: `--url` (required), `--level`, `--suite`, `--output`, `--quiet`,
22
+ `--federation` (L3, requires the `federation` extra: `pip install "banza-conformance[federation]"`).
23
+ The CLI calls the same conformance logic as `run.py` — `python3 tools/banza-conformance/run.py …`
24
+ continues to work unchanged.
25
+
26
+ On completion the tool prints:
27
+
28
+ ```
29
+ Conformance report generated. This is evidence, not certification.
30
+ ```
31
+
32
+ ### Client identity (User-Agent)
33
+
34
+ The runner sends a stable, documented User-Agent so operators can allow it in
35
+ WAF / proxy / CDN configurations:
36
+
37
+ ```
38
+ BANZA-Conformance/1.0 (+https://banza.org/conformance)
39
+ ```
40
+
41
+ If your sandbox endpoint sits behind a bot filter (e.g. Cloudflare), allow this
42
+ User-Agent (or the `/health` and `/.well-known/banza/*` paths) so the runner can reach it.
43
+ The User-Agent identifies the client cleanly; it does not bypass any security control.
44
+
45
+ ### Docker
46
+
47
+ ```bash
48
+ docker run --rm \
49
+ -v "$PWD/reports:/reports" \
50
+ ghcr.io/banza-protocol/banza-conformance:latest \
51
+ --url https://sandbox.operator.example \
52
+ --level 0 \
53
+ --output /reports/banza-l0-report.json
54
+ ```
55
+
56
+ Build the image locally (context = this directory):
57
+
58
+ ```bash
59
+ docker build -t banza-conformance:local tools/banza-conformance
60
+ ```
61
+
62
+ The entrypoint is `banza-conformance`; arguments after the image name are passed
63
+ straight through. Reports are written under `/reports` — mount a host volume there.
64
+
65
+ ### GitHub Action
66
+
67
+ Run BANZA conformance in your CI/CD against your public sandbox endpoint:
68
+
69
+ ```yaml
70
+ name: BANZA Conformance
71
+
72
+ on:
73
+ workflow_dispatch:
74
+ pull_request:
75
+ push:
76
+
77
+ jobs:
78
+ conformance:
79
+ runs-on: ubuntu-latest
80
+ steps:
81
+ - uses: actions/checkout@v4
82
+ - uses: banza-protocol/banza/.github/actions/banza-conformance@main
83
+ with:
84
+ url: https://sandbox.operator.example
85
+ level: "0"
86
+ output: banza-l0-report.json
87
+ - uses: actions/upload-artifact@v4
88
+ with:
89
+ name: banza-conformance-report
90
+ path: banza-l0-report.json
91
+ ```
92
+
93
+ Inputs: `url` (required), `level` (default `"0"`), `output`
94
+ (default `"banza-conformance-report.json"`), `suite`, `federation`, `quiet`.
95
+
96
+ ## Requirements
97
+
98
+ Python 3.8+. No third-party packages for the core runner — stdlib only.
99
+
100
+ For L3 federation conformance (signature verification): `pip install cryptography>=41.0.0`
101
+
102
+ ## Usage
103
+
104
+ ### Standard conformance (L0–L4)
105
+
106
+ ```bash
107
+ # Run all suites against a local operator
108
+ python3 tools/banza-conformance/run.py --url http://localhost:3000
109
+
110
+ # Run up to Level 2 only
111
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --level 2
112
+
113
+ # Run a single suite
114
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --suite health
115
+
116
+ # Write report to file (quiet mode)
117
+ python3 tools/banza-conformance/run.py --url http://localhost:3000 --output report.json --quiet
118
+ ```
119
+
120
+ Or via the shell wrapper:
121
+
122
+ ```bash
123
+ ./tools/banza-conformance/run.sh --url http://localhost:3000 --output report.json
124
+ ```
125
+
126
+ ### L3 Federation Conformance (79 tests, 9 suites)
127
+
128
+ The federation conformance suite tests cross-operator federation protocol compliance.
129
+ It requires two terminals: one for the fixture server (Operator A adapter) and one for the runner.
130
+
131
+ ```bash
132
+ # Terminal 1 — start the fixture server (Operator A)
133
+ python3 tools/banza-conformance/fixture_server.py --port 8099
134
+
135
+ # Terminal 2 — run the full federation suite (79 tests)
136
+ python3 tools/banza-conformance/run.py \
137
+ --federation \
138
+ --url http://localhost:8099 \
139
+ --output l3-report.json
140
+
141
+ # Run only one federation sub-suite
142
+ python3 tools/banza-conformance/run.py \
143
+ --federation \
144
+ --url http://localhost:8099 \
145
+ --fed-suite cert # cert | disc | trust | route | exec | obl | evt | settle | fail
146
+ ```
147
+
148
+ **What the federation runner does:**
149
+ - Generates an ephemeral test BANZA root keypair (never reused as production)
150
+ - Spins up an embedded Simulated Operator B (random port, in-process)
151
+ - Spins up an embedded test BRL/key-manifest server (random port, in-process)
152
+ - Runs all 79 federation tests against the fixture server
153
+ - Produces a structured JSON evidence report
154
+
155
+ **Federation suites:**
156
+
157
+ | Suite | Cases | Blocking | What it tests |
158
+ |---|---|---|---|
159
+ | FED-CERT | 11 | Yes | Certificate schema, signature, expiry, BRL |
160
+ | FED-DISC | 8 | Yes | Federation manifest extension fields |
161
+ | FED-TRUST | 9 | Yes | All 9 ADR-026 trust protocol steps |
162
+ | FED-ROUTE | 12 | Yes | Routing wire protocol, idempotency, rejections |
163
+ | FED-EXEC | 8 | Yes | Acceptance semantics, ledger atomicity |
164
+ | FED-OBL | 7 | Yes | Obligation creation, signature, state machine |
165
+ | FED-EVT | 6 | No | Federation event emission and schema |
166
+ | FED-SETTLE | 10 | No | Netting, settlement, reconciliation |
167
+ | FED-FAIL | 8 | No | Retry, crash recovery, revocation, mismatches |
168
+
169
+ **L3 certification decision:** All blocking suites (FED-CERT through FED-OBL) must PASS. FAIL in a blocking suite denies certification. FAIL in a non-blocking suite produces conditional certification (30-day remediation window).
170
+
171
+ See `docs/federation/FEDERATION_CONFORMANCE_MODEL.md` for the full decision rules.
172
+
173
+ ## Options
174
+
175
+ | Flag | Description |
176
+ |------|-------------|
177
+ | `--url` | Base URL of the operator (required) |
178
+ | `--level` | Maximum certification level to test, 0–4 (default 4) |
179
+ | `--suite` | Run one suite only: `health`, `wallets`, `transfers`, `traces`, `manifest` |
180
+ | `--output` | Write JSON report to this path (default: stdout) |
181
+ | `--quiet` | Suppress PASS lines; only print failures and summary |
182
+
183
+ ## Certification levels
184
+
185
+ | Level | Name | Runner suites | Awarded here |
186
+ |-------|------|---------------|--------------|
187
+ | L0 | Protocol Sandbox | health, manifest (sandbox-safety) | Yes |
188
+ | L1 | Core Payment Capability | + wallets, transfers, traces (traceability) | Yes |
189
+ | L2 | Payment Initiation Capability | + payment_initiation (payment requests, dynamic QR, instant execution) | Yes |
190
+ | L3 | Inter-Operator Interoperability | federation suite — run via `--federation` (`run_fed.py`) | No (multi-operator) |
191
+ | L4 | External Interoperability | External Interoperability profile (external-rail evidence) | No (profile) |
192
+
193
+ Level names **and per-level capabilities** are canonical and match
194
+ `BANZA_CERTIFICATION.md` § Conformance level model and ADR-034. This
195
+ single-operator sandbox runner awards **L0–L2**; L3 (federation) and L4 (external)
196
+ require multi-operator / external-rail evidence and are not awarded here.
197
+
198
+ ## Exit codes
199
+
200
+ | Code | Meaning |
201
+ |------|---------|
202
+ | 0 | All executed cases passed |
203
+ | 1 | One or more cases failed |
204
+ | 2 | Runner error (connectivity, bad arguments) |
205
+
206
+ ## Report format
207
+
208
+ Reports conform to `conformance/report-schema.json`. Each case records:
209
+ - `status`: PASS / FAIL / SKIP / ERROR
210
+ - `request` and `response` for HTTP cases
211
+ - `assertions`: per-field check results
212
+ - `failure_reason`: human-readable explanation on failure
213
+
214
+ ## Adding new suites
215
+
216
+ 1. Implement a runner function `run_<name>(base_url, ctx) -> list[CaseResult]`
217
+ 2. Register it in the `SUITES` dict
218
+ 3. Add it to the relevant `LEVEL_SUITES` entries
219
+ 4. Add the corresponding vectors in `conformance/vectors/`
@@ -0,0 +1,7 @@
1
+ """BANZA protocol conformance runner.
2
+
3
+ Generates conformance evidence (not certification) for an operator endpoint.
4
+ Public entry point: banza_conformance.run:main (console script `banza-conformance`).
5
+ """
6
+
7
+ __version__ = "0.1.0"